[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.15-54-g0b2d96d

Lennart Poettering gitmailer-noreply at 0pointer.de
Tue Apr 28 17:00:25 PDT 2009


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master branch has been updated
      from  908b0e6738778d4e7244391bcccecb8a0db542aa (commit)

- Log -----------------------------------------------------------------
0b2d96d protocol-http: substantial modernizations
d871071 alsa: allow configuration of fallback device strings in profiles
ad5a1f3 protocol-native,proplist-util: port to pa_get_{user|host}_name_malloc()
a8f0d7e core-util: introduce pa_get_host_name_malloc() and pa_get_user_name_malloc()
4abd5fa memtrap: implicitly page align memory areas
bd0e4ce macro: make pa_page_align roung up instead of down
68f3ca9 macro: add new macro pa_align_ptr()
8247e45 shm: minor modernizations
595c22a shm: page align shm size when mmap()ing it
9745483 strbuf: add new call pa_strbuf_putc()
5d39b8d idxset: add enumeration macro PA_IDXSET_FOREACH
0368d6e build-system: move x11 and jack modules into subdirectories
-----------------------------------------------------------------------

Summary of changes:
 src/Makefile.am                                 |   24 +-
 src/modules/alsa/alsa-util.c                    |  126 ++++--
 src/modules/alsa/alsa-util.h                    |    1 +
 src/modules/{ => jack}/module-jack-sink.c       |    0
 src/modules/{ => jack}/module-jack-source.c     |    0
 src/modules/{ => x11}/module-x11-bell.c         |    0
 src/modules/{ => x11}/module-x11-cork-request.c |    0
 src/modules/{ => x11}/module-x11-publish.c      |    0
 src/modules/{ => x11}/module-x11-xsmp.c         |    0
 src/pulsecore/core-util.c                       |   65 ++-
 src/pulsecore/core-util.h                       |    3 +
 src/pulsecore/idxset.h                          |    4 +
 src/pulsecore/macro.h                           |   11 +-
 src/pulsecore/memtrap.c                         |   10 +-
 src/pulsecore/proplist-util.c                   |   20 +-
 src/pulsecore/protocol-http.c                   |  497 ++++++++++++++++++-----
 src/pulsecore/protocol-native.c                 |   12 +-
 src/pulsecore/shm.c                             |   12 +-
 src/pulsecore/strbuf.c                          |    7 +
 src/pulsecore/strbuf.h                          |    1 +
 20 files changed, 598 insertions(+), 195 deletions(-)
 rename src/modules/{ => jack}/module-jack-sink.c (100%)
 rename src/modules/{ => jack}/module-jack-source.c (100%)
 rename src/modules/{ => x11}/module-x11-bell.c (100%)
 rename src/modules/{ => x11}/module-x11-cork-request.c (100%)
 rename src/modules/{ => x11}/module-x11-publish.c (100%)
 rename src/modules/{ => x11}/module-x11-xsmp.c (100%)

-----------------------------------------------------------------------

commit 0368d6e22b9d7e6fec2474d158eaec16c90054f5
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Apr 28 02:29:01 2009 +0200

    build-system: move x11 and jack modules into subdirectories

diff --git a/src/Makefile.am b/src/Makefile.am
index 68b42df..719f9dd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1115,10 +1115,10 @@ SYMDEF_FILES = \
 		modules/module-mmkbd-evdev-symdef.h \
 		modules/module-http-protocol-tcp-symdef.h \
 		modules/module-http-protocol-unix-symdef.h \
-		modules/module-x11-bell-symdef.h \
-		modules/module-x11-publish-symdef.h \
-		modules/module-x11-xsmp-symdef.h \
-		modules/module-x11-cork-request-symdef.h \
+		modules/x11/module-x11-bell-symdef.h \
+		modules/x11/module-x11-publish-symdef.h \
+		modules/x11/module-x11-xsmp-symdef.h \
+		modules/x11/module-x11-cork-request-symdef.h \
 		modules/oss/module-oss-symdef.h \
 		modules/alsa/module-alsa-sink-symdef.h \
 		modules/alsa/module-alsa-source-symdef.h \
@@ -1128,8 +1128,8 @@ SYMDEF_FILES = \
 		modules/module-detect-symdef.h \
 		modules/rtp/module-rtp-send-symdef.h \
 		modules/rtp/module-rtp-recv-symdef.h \
-		modules/module-jack-sink-symdef.h \
-		modules/module-jack-source-symdef.h \
+		modules/jack/module-jack-sink-symdef.h \
+		modules/jack/module-jack-source-symdef.h \
 		modules/module-volume-restore-symdef.h \
 		modules/module-device-restore-symdef.h \
 		modules/module-stream-restore-symdef.h \
@@ -1292,22 +1292,22 @@ module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore- at PA_MAJORMINORMICRO@.
 
 # X11
 
-module_x11_bell_la_SOURCES = modules/module-x11-bell.c
+module_x11_bell_la_SOURCES = modules/x11/module-x11-bell.c
 module_x11_bell_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_bell_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_x11_bell_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libpulsecore- at PA_MAJORMINORMICRO@.la libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
 
-module_x11_publish_la_SOURCES = modules/module-x11-publish.c
+module_x11_publish_la_SOURCES = modules/x11/module-x11-publish.c
 module_x11_publish_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_publish_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libprotocol-native.la libpulsecore- at PA_MAJORMINORMICRO@.la libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
 
-module_x11_xsmp_la_SOURCES = modules/module-x11-xsmp.c
+module_x11_xsmp_la_SOURCES = modules/x11/module-x11-xsmp.c
 module_x11_xsmp_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_xsmp_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libpulsecore- at PA_MAJORMINORMICRO@.la libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
 
-module_x11_cork_request_la_SOURCES = modules/module-x11-cork-request.c
+module_x11_cork_request_la_SOURCES = modules/x11/module-x11-cork-request.c
 module_x11_cork_request_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_cork_request_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_x11_cork_request_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libpulsecore- at PA_MAJORMINORMICRO@.la libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
@@ -1487,12 +1487,12 @@ module_rtp_recv_la_CFLAGS = $(AM_CFLAGS)
 
 # JACK
 
-module_jack_sink_la_SOURCES = modules/module-jack-sink.c
+module_jack_sink_la_SOURCES = modules/jack/module-jack-sink.c
 module_jack_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore- at PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
 module_jack_sink_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
 
-module_jack_source_la_SOURCES = modules/module-jack-source.c
+module_jack_source_la_SOURCES = modules/jack/module-jack-source.c
 module_jack_source_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore- at PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
 module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
diff --git a/src/modules/module-jack-sink.c b/src/modules/jack/module-jack-sink.c
similarity index 100%
rename from src/modules/module-jack-sink.c
rename to src/modules/jack/module-jack-sink.c
diff --git a/src/modules/module-jack-source.c b/src/modules/jack/module-jack-source.c
similarity index 100%
rename from src/modules/module-jack-source.c
rename to src/modules/jack/module-jack-source.c
diff --git a/src/modules/module-x11-bell.c b/src/modules/x11/module-x11-bell.c
similarity index 100%
rename from src/modules/module-x11-bell.c
rename to src/modules/x11/module-x11-bell.c
diff --git a/src/modules/module-x11-cork-request.c b/src/modules/x11/module-x11-cork-request.c
similarity index 100%
rename from src/modules/module-x11-cork-request.c
rename to src/modules/x11/module-x11-cork-request.c
diff --git a/src/modules/module-x11-publish.c b/src/modules/x11/module-x11-publish.c
similarity index 100%
rename from src/modules/module-x11-publish.c
rename to src/modules/x11/module-x11-publish.c
diff --git a/src/modules/module-x11-xsmp.c b/src/modules/x11/module-x11-xsmp.c
similarity index 100%
rename from src/modules/module-x11-xsmp.c
rename to src/modules/x11/module-x11-xsmp.c

commit 5d39b8d22d4cce197778d8ef554a88c4be116f92
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:46:12 2009 +0200

    idxset: add enumeration macro PA_IDXSET_FOREACH

diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h
index 7531ea3..6b9ff47 100644
--- a/src/pulsecore/idxset.h
+++ b/src/pulsecore/idxset.h
@@ -103,4 +103,8 @@ unsigned pa_idxset_size(pa_idxset*s);
 /* Return TRUE of the idxset is empty */
 pa_bool_t pa_idxset_isempty(pa_idxset *s);
 
+
+#define PA_IDXSET_FOREACH(e, s, idx) \
+    for ((e) = pa_idxset_first((s), &(idx)); (e); (e) = pa_idxset_next((s), &(idx)))
+
 #endif

commit 9745483cddb70c6414c8b548f712df4ff9317f43
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:46:51 2009 +0200

    strbuf: add new call pa_strbuf_putc()

diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c
index 9f5a84b..4fc82de 100644
--- a/src/pulsecore/strbuf.c
+++ b/src/pulsecore/strbuf.c
@@ -113,6 +113,13 @@ void pa_strbuf_puts(pa_strbuf *sb, const char *t) {
     pa_strbuf_putsn(sb, t, strlen(t));
 }
 
+/* Append a character to the string buffer */
+void pa_strbuf_putc(pa_strbuf *sb, char c) {
+    pa_assert(sb);
+
+    pa_strbuf_putsn(sb, &c, 1);
+}
+
 /* Append a new chunk to the linked list */
 static void append(pa_strbuf *sb, struct chunk *c) {
     pa_assert(sb);
diff --git a/src/pulsecore/strbuf.h b/src/pulsecore/strbuf.h
index 05e69e0..d71ecb9 100644
--- a/src/pulsecore/strbuf.h
+++ b/src/pulsecore/strbuf.h
@@ -35,6 +35,7 @@ char *pa_strbuf_tostring_free(pa_strbuf *sb);
 size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...)  PA_GCC_PRINTF_ATTR(2,3);
 void pa_strbuf_puts(pa_strbuf *sb, const char *t);
 void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t m);
+void pa_strbuf_putc(pa_strbuf *sb, char c);
 
 pa_bool_t pa_strbuf_isempty(pa_strbuf *sb);
 

commit 595c22a3ad2ac55e141959ada634d4cd0aa86aad
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:49:02 2009 +0200

    shm: page align shm size when mmap()ing it

diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c
index b8c5f78..fe556da 100644
--- a/src/pulsecore/shm.c
+++ b/src/pulsecore/shm.c
@@ -105,7 +105,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
         m->size = size;
 
 #ifdef MAP_ANONYMOUS
-        if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
+        if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
             pa_log("mmap() failed: %s", pa_cstrerror(errno));
             goto fail;
         }
@@ -143,7 +143,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
             goto fail;
         }
 
-        if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
+        if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
             pa_log("mmap() failed: %s", pa_cstrerror(errno));
             goto fail;
         }
@@ -291,7 +291,7 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) {
 
     m->size = (size_t) st.st_size;
 
-    if ((m->ptr = mmap(NULL, m->size, PROT_READ, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
+    if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
         pa_log("mmap() failed: %s", pa_cstrerror(errno));
         goto fail;
     }

commit 8247e4555b267ff85a386712633427dd689d2aa1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:49:22 2009 +0200

    shm: minor modernizations

diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c
index fe556da..5b9e960 100644
--- a/src/pulsecore/shm.c
+++ b/src/pulsecore/shm.c
@@ -154,7 +154,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
         pa_atomic_store(&marker->pid, (int) getpid());
         pa_atomic_store(&marker->marker, SHM_MARKER);
 
-        pa_assert_se(close(fd) == 0);
+        pa_assert_se(pa_close(fd) == 0);
         m->do_unlink = TRUE;
 #else
         return -1;
@@ -296,8 +296,8 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) {
         goto fail;
     }
 
-    m->do_unlink = 0;
-    m->shared = 1;
+    m->do_unlink = FALSE;
+    m->shared = TRUE;
 
     pa_assert_se(pa_close(fd) == 0);
 

commit 68f3ca9831a0ede7439348d0cd952f7730305bca
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:52:11 2009 +0200

    macro: add new macro pa_align_ptr()

diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h
index a5ca696..2f6ee90 100644
--- a/src/pulsecore/macro.h
+++ b/src/pulsecore/macro.h
@@ -57,11 +57,19 @@
 #define PA_PAGE_SIZE ((size_t) 4096)
 #endif
 
+/* Rounds down */
+static inline void* pa_align_ptr(const void *p) {
+    return (void*) (((size_t) p) & ~(sizeof(void*)-1));
+}
+#define PA_ALIGN_PTR(x) (pa_align_ptr(x))
+
+/* Rounds up */
 static inline size_t pa_align(size_t l) {
     return (((l + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*));
 }
 #define PA_ALIGN(x) (pa_align(x))
 
+/* Rounds down */
 static inline void* pa_page_align_ptr(const void *p) {
     return (void*) (((size_t) p) & ~(PA_PAGE_SIZE-1));
 }

commit bd0e4ceb857f3e7891e0d5aeebaa6e2144986ccb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:52:28 2009 +0200

    macro: make pa_page_align roung up instead of down

diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h
index 2f6ee90..73438e6 100644
--- a/src/pulsecore/macro.h
+++ b/src/pulsecore/macro.h
@@ -75,8 +75,9 @@ static inline void* pa_page_align_ptr(const void *p) {
 }
 #define PA_PAGE_ALIGN_PTR(x) (pa_page_align_ptr(x))
 
+/* Rounds up */
 static inline size_t pa_page_align(size_t l) {
-    return l & ~(PA_PAGE_SIZE-1);
+    return ((l + PA_PAGE_SIZE - 1) / PA_PAGE_SIZE) * PA_PAGE_SIZE;
 }
 #define PA_PAGE_ALIGN(x) (pa_page_align(x))
 

commit 4abd5fae1431d47398d3b007fdceac5fda7607a8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:53:28 2009 +0200

    memtrap: implicitly page align memory areas

diff --git a/src/pulsecore/memtrap.c b/src/pulsecore/memtrap.c
index bd0243e..601fef4 100644
--- a/src/pulsecore/memtrap.c
+++ b/src/pulsecore/memtrap.c
@@ -122,8 +122,9 @@ pa_memtrap* pa_memtrap_add(const void *start, size_t size) {
 
     pa_assert(start);
     pa_assert(size > 0);
-    pa_assert(PA_PAGE_ALIGN_PTR(start) == start);
-    pa_assert(PA_PAGE_ALIGN(size) == size);
+
+    start = PA_PAGE_ALIGN_PTR(start);
+    size = PA_PAGE_ALIGN(size);
 
     m = pa_xnew(pa_memtrap, 1);
     m->start = (void*) start;
@@ -164,8 +165,9 @@ pa_memtrap *pa_memtrap_update(pa_memtrap *m, const void *start, size_t size) {
 
     pa_assert(start);
     pa_assert(size > 0);
-    pa_assert(PA_PAGE_ALIGN_PTR(start) == start);
-    pa_assert(PA_PAGE_ALIGN(size) == size);
+
+    start = PA_PAGE_ALIGN_PTR(start);
+    size = PA_PAGE_ALIGN(size);
 
     allocate_aupdate();
 

commit a8f0d7ec1e5cb3f52c4b1abfce1016ed6d9b00f8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:54:44 2009 +0200

    core-util: introduce pa_get_host_name_malloc() and pa_get_user_name_malloc()

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 294f63c..4658eb5 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2467,31 +2467,29 @@ pa_bool_t pa_in_system_mode(void) {
     return !!atoi(e);
 }
 
-char *pa_machine_id(void) {
-    FILE *f;
-    size_t l;
-
-    /* The returned value is supposed be some kind of ascii identifier
-     * that is unique and stable across reboots. */
+char *pa_get_user_name_malloc(void) {
+    ssize_t k;
+    char *u;
 
-    /* First we try the D-Bus UUID, which is the best option we have,
-     * since it fits perfectly our needs and is not as volatile as the
-     * hostname which might be set from dhcp. */
-
-    if ((f = fopen(PA_MACHINE_ID, "r"))) {
-        char ln[34] = "", *r;
+#ifdef _SC_LOGIN_NAME_MAX
+    k = (ssize_t) sysconf(_SC_LOGIN_NAME_MAX);
 
-        r = fgets(ln, sizeof(ln)-1, f);
-        fclose(f);
+    if (k <= 0)
+#endif
+        k = 32;
 
-        pa_strip_nl(ln);
+    u = pa_xnew(char, k+1);
 
-        if (r && ln[0])
-            return pa_utf8_filter(ln);
+    if (!(pa_get_user_name(u, k))) {
+        pa_xfree(u);
+        return NULL;
     }
 
-    /* The we fall back to the host name. It supposed to be somewhat
-     * unique, at least in a network, but may change. */
+    return u;
+}
+
+char *pa_get_host_name_malloc(void) {
+    size_t l;
 
     l = 100;
     for (;;) {
@@ -2525,6 +2523,35 @@ char *pa_machine_id(void) {
         l *= 2;
     }
 
+    return NULL;
+}
+
+char *pa_machine_id(void) {
+    FILE *f;
+    char *h;
+
+    /* The returned value is supposed be some kind of ascii identifier
+     * that is unique and stable across reboots. */
+
+    /* First we try the D-Bus UUID, which is the best option we have,
+     * since it fits perfectly our needs and is not as volatile as the
+     * hostname which might be set from dhcp. */
+
+    if ((f = fopen(PA_MACHINE_ID, "r"))) {
+        char ln[34] = "", *r;
+
+        r = fgets(ln, sizeof(ln)-1, f);
+        fclose(f);
+
+        pa_strip_nl(ln);
+
+        if (r && ln[0])
+            return pa_utf8_filter(ln);
+    }
+
+    if ((h = pa_get_host_name_malloc()))
+        return h;
+
     /* If no hostname was set we use the POSIX hostid. It's usually
      * the IPv4 address.  Might not be that stable. */
     return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index f96fa44..91a4c55 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -201,6 +201,9 @@ pa_bool_t pa_in_system_mode(void);
 
 #define pa_streq(a,b) (!strcmp((a),(b)))
 
+char *pa_get_host_name_malloc(void);
+char *pa_get_user_name_malloc(void);
+
 char *pa_machine_id(void);
 char *pa_session_id(void);
 char *pa_uname_string(void);

commit ad5a1f312aaa5511863ad4c9341f735b9ac4b6a3
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:56:02 2009 +0200

    protocol-native,proplist-util: port to pa_get_{user|host}_name_malloc()

diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c
index eac8927..d9769bc 100644
--- a/src/pulsecore/proplist-util.c
+++ b/src/pulsecore/proplist-util.c
@@ -168,20 +168,20 @@ void pa_init_proplist(pa_proplist *p) {
     }
 
     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_USER)) {
-        char t[64];
-        if (pa_get_user_name(t, sizeof(t))) {
-            char *c = pa_utf8_filter(t);
-            pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_USER, c);
-            pa_xfree(c);
+        char *u;
+
+        if ((u = pa_get_user_name_malloc())) {
+            pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_USER, u);
+            pa_xfree(u);
         }
     }
 
     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_HOST)) {
-        char t[64];
-        if (pa_get_host_name(t, sizeof(t))) {
-            char *c = pa_utf8_filter(t);
-            pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_HOST, c);
-            pa_xfree(c);
+        char *h;
+
+        if ((h = pa_get_host_name_malloc())) {
+            pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_HOST, h);
+            pa_xfree(h);
         }
     }
 
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index aecaf71..d4a9952 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -3182,10 +3182,10 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
 static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
     pa_tagstruct *reply;
-    char txt[256];
     pa_sink *def_sink;
     pa_source *def_source;
     pa_sample_spec fixed_ss;
+    char *h, *u;
 
     pa_native_connection_assert_ref(c);
     pa_assert(t);
@@ -3200,8 +3200,14 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t
     reply = reply_new(tag);
     pa_tagstruct_puts(reply, PACKAGE_NAME);
     pa_tagstruct_puts(reply, PACKAGE_VERSION);
-    pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt)));
-    pa_tagstruct_puts(reply, pa_get_host_name(txt, sizeof(txt)));
+
+    u = pa_get_user_name_malloc();
+    pa_tagstruct_puts(reply, u);
+    pa_xfree(u);
+
+    h = pa_get_host_name_malloc();
+    pa_tagstruct_puts(reply, h);
+    pa_xfree(h);
 
     fixup_sample_spec(c, &fixed_ss, &c->protocol->core->default_sample_spec);
     pa_tagstruct_put_sample_spec(reply, &fixed_ss);

commit d8710711fb0c74b4ad83ac99c2501218155b502b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 01:58:18 2009 +0200

    alsa: allow configuration of fallback device strings in profiles
    
    This has the benefit that we can properly support ALSA devices where
    only the raw 'hw' device exists but no 'front' although it's a proper
    2ch stereo device.

diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
index 18d6880..a3a0450 100644
--- a/src/modules/alsa/alsa-util.c
+++ b/src/modules/alsa/alsa-util.c
@@ -528,7 +528,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min) {
 
 static const struct pa_alsa_profile_info device_table[] = {
     {{ 1, { PA_CHANNEL_POSITION_MONO }},
-     "hw",
+     "hw", NULL,
      N_("Analog Mono"),
      "analog-mono",
      1,
@@ -536,7 +536,7 @@ static const struct pa_alsa_profile_info device_table[] = {
      "Capture", "Mic" },
 
     {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
-     "front",
+     "front", "hw",
      N_("Analog Stereo"),
      "analog-stereo",
      10,
@@ -544,7 +544,7 @@ static const struct pa_alsa_profile_info device_table[] = {
      "Capture", "Mic" },
 
     {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
-     "iec958",
+     "iec958", NULL,
      N_("Digital Stereo (IEC958)"),
      "iec958-stereo",
      5,
@@ -552,7 +552,7 @@ static const struct pa_alsa_profile_info device_table[] = {
      "IEC958 In", NULL },
 
     {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
-     "hdmi",
+     "hdmi", NULL,
      N_("Digital Stereo (HDMI)"),
      "hdmi-stereo",
      4,
@@ -561,7 +561,7 @@ static const struct pa_alsa_profile_info device_table[] = {
 
     {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }},
-     "surround40",
+     "surround40", NULL,
      N_("Analog Surround 4.0"),
      "analog-surround-40",
      7,
@@ -570,7 +570,7 @@ static const struct pa_alsa_profile_info device_table[] = {
 
     {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }},
-     "a52",
+     "a52", NULL,
      N_("Digital Surround 4.0 (IEC958/AC3)"),
      "iec958-ac3-surround-40",
      2,
@@ -580,7 +580,7 @@ static const struct pa_alsa_profile_info device_table[] = {
     {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
             PA_CHANNEL_POSITION_LFE }},
-     "surround41",
+     "surround41", NULL,
      N_("Analog Surround 4.1"),
      "analog-surround-41",
      7,
@@ -590,7 +590,7 @@ static const struct pa_alsa_profile_info device_table[] = {
     {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
             PA_CHANNEL_POSITION_CENTER }},
-     "surround50",
+     "surround50", NULL,
      N_("Analog Surround 5.0"),
      "analog-surround-50",
      7,
@@ -600,7 +600,7 @@ static const struct pa_alsa_profile_info device_table[] = {
     {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
             PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE }},
-     "surround51",
+     "surround51", NULL,
      N_("Analog Surround 5.1"),
      "analog-surround-51",
      8,
@@ -610,7 +610,7 @@ static const struct pa_alsa_profile_info device_table[] = {
     {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
             PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE}},
-     "a52",
+     "a52", NULL,
      N_("Digital Surround 5.1 (IEC958/AC3)"),
      "iec958-ac3-surround-51",
      3,
@@ -621,16 +621,72 @@ static const struct pa_alsa_profile_info device_table[] = {
             PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
             PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE,
             PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT }},
-     "surround71",
+     "surround71", NULL,
      N_("Analog Surround 7.1"),
      "analog-surround-71",
      7,
      "Master", "PCM",
      "Capture", "Mic" },
 
-    {{ 0, { 0 }}, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
+    {{ 0, { 0 }}, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
 };
 
+static snd_pcm_t *open_by_device_string_with_fallback(
+        const char *prefix,
+        const char *prefix_fallback,
+        const char *dev_id,
+        char **dev,
+        pa_sample_spec *ss,
+        pa_channel_map* map,
+        int mode,
+        uint32_t *nfrags,
+        snd_pcm_uframes_t *period_size,
+        snd_pcm_uframes_t tsched_size,
+        pa_bool_t *use_mmap,
+        pa_bool_t *use_tsched,
+        pa_bool_t require_exact_channel_number) {
+
+    snd_pcm_t *pcm_handle;
+    char *d;
+
+    d = pa_sprintf_malloc("%s:%s", prefix, dev_id);
+
+    pcm_handle = pa_alsa_open_by_device_string(
+            d,
+            dev,
+            ss,
+            map,
+            mode,
+            nfrags,
+            period_size,
+            tsched_size,
+            use_mmap,
+            use_tsched,
+            require_exact_channel_number);
+    pa_xfree(d);
+
+    if (!pcm_handle && prefix_fallback) {
+
+        d = pa_sprintf_malloc("%s:%s", prefix_fallback, dev_id);
+
+        pcm_handle = pa_alsa_open_by_device_string(
+                d,
+                dev,
+                ss,
+                map,
+                mode,
+                nfrags,
+                period_size,
+                tsched_size,
+                use_mmap,
+                use_tsched,
+                require_exact_channel_number);
+        pa_xfree(d);
+    }
+
+    return pcm_handle;
+}
+
 snd_pcm_t *pa_alsa_open_by_device_id_auto(
         const char *dev_id,
         char **dev,
@@ -671,14 +727,14 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
 
             pa_log_debug("Checking for %s (%s)", device_table[i].name, device_table[i].alsa_name);
 
-            d = pa_sprintf_malloc("%s:%s", device_table[i].alsa_name, dev_id);
-
             try_ss.channels = device_table[i].map.channels;
             try_ss.rate = ss->rate;
             try_ss.format = ss->format;
 
-            pcm_handle = pa_alsa_open_by_device_string(
-                    d,
+            pcm_handle = open_by_device_string_with_fallback(
+                    device_table[i].alsa_name,
+                    device_table[i].alsa_name_fallback,
+                    dev_id,
                     dev,
                     &try_ss,
                     map,
@@ -690,8 +746,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
                     use_tsched,
                     TRUE);
 
-            pa_xfree(d);
-
             if (pcm_handle) {
 
                 *ss = try_ss;
@@ -703,6 +757,7 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
 
                 return pcm_handle;
             }
+
         }
 
         if (direction > 0) {
@@ -775,7 +830,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_profile(
         pa_bool_t *use_tsched,
         const pa_alsa_profile_info *profile) {
 
-    char *d;
     snd_pcm_t *pcm_handle;
     pa_sample_spec try_ss;
 
@@ -787,14 +841,14 @@ snd_pcm_t *pa_alsa_open_by_device_id_profile(
     pa_assert(period_size);
     pa_assert(profile);
 
-    d = pa_sprintf_malloc("%s:%s", profile->alsa_name, dev_id);
-
     try_ss.channels = profile->map.channels;
     try_ss.rate = ss->rate;
     try_ss.format = ss->format;
 
-    pcm_handle = pa_alsa_open_by_device_string(
-            d,
+    pcm_handle = open_by_device_string_with_fallback(
+            profile->alsa_name,
+            profile->alsa_name_fallback,
+            dev_id,
             dev,
             &try_ss,
             map,
@@ -806,8 +860,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_profile(
             use_tsched,
             TRUE);
 
-    pa_xfree(d);
-
     if (!pcm_handle)
         return NULL;
 
@@ -860,6 +912,8 @@ snd_pcm_t *pa_alsa_open_by_device_string(
             goto fail;
         }
 
+        pa_log_debug("Managed to open %s", d);
+
         if ((err = pa_alsa_set_hw_params(pcm_handle, ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, require_exact_channel_number)) < 0) {
 
             if (!reformat) {
@@ -928,26 +982,25 @@ int pa_alsa_probe_profiles(
         snd_pcm_t *pcm_i = NULL;
 
         if (i->alsa_name) {
-            char *id;
             pa_sample_spec try_ss;
             pa_channel_map try_map;
 
             pa_log_debug("Checking for playback on %s (%s)", i->name, i->alsa_name);
-            id = pa_sprintf_malloc("%s:%s", i->alsa_name, dev_id);
 
             try_ss = *ss;
             try_ss.channels = i->map.channels;
             try_map = i->map;
 
-            pcm_i = pa_alsa_open_by_device_string(
-                    id, NULL,
+            pcm_i = open_by_device_string_with_fallback(
+                    i->alsa_name,
+                    i->alsa_name_fallback,
+                    dev_id,
+                    NULL,
                     &try_ss, &try_map,
                     SND_PCM_STREAM_PLAYBACK,
                     NULL, NULL, 0, NULL, NULL,
                     TRUE);
 
-            pa_xfree(id);
-
             if (!pcm_i)
                 continue;
         }
@@ -956,26 +1009,25 @@ int pa_alsa_probe_profiles(
             snd_pcm_t *pcm_j = NULL;
 
             if (j->alsa_name) {
-                char *jd;
                 pa_sample_spec try_ss;
                 pa_channel_map try_map;
 
                 pa_log_debug("Checking for capture on %s (%s)", j->name, j->alsa_name);
-                jd = pa_sprintf_malloc("%s:%s", j->alsa_name, dev_id);
 
                 try_ss = *ss;
                 try_ss.channels = j->map.channels;
                 try_map = j->map;
 
-                pcm_j = pa_alsa_open_by_device_string(
-                        jd, NULL,
+                pcm_j = open_by_device_string_with_fallback(
+                        j->alsa_name,
+                        j->alsa_name_fallback,
+                        dev_id,
+                        NULL,
                         &try_ss, &try_map,
                         SND_PCM_STREAM_CAPTURE,
                         NULL, NULL, 0, NULL, NULL,
                         TRUE);
 
-                pa_xfree(jd);
-
                 if (!pcm_j)
                     continue;
             }
diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h
index 77ac8a7..4c5d336 100644
--- a/src/modules/alsa/alsa-util.h
+++ b/src/modules/alsa/alsa-util.h
@@ -56,6 +56,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min);
 typedef struct pa_alsa_profile_info {
     pa_channel_map map;
     const char *alsa_name;
+    const char *alsa_name_fallback;
     const char *description; /* internationalized */
     const char *name;
     unsigned priority;

commit 0b2d96d6c0f586bb8436950080eda11daa170ba3
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 29 02:00:19 2009 +0200

    protocol-http: substantial modernizations

diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c
index f3b9381..08a70e5 100644
--- a/src/pulsecore/protocol-http.c
+++ b/src/pulsecore/protocol-http.c
@@ -42,20 +42,39 @@
 /* Don't allow more than this many concurrent connections */
 #define MAX_CONNECTIONS 10
 
-#define internal_server_error(c) http_message((c), 500, "Internal Server Error", NULL)
-
 #define URL_ROOT "/"
 #define URL_CSS "/style"
 #define URL_STATUS "/status"
+#define URL_LISTEN "/listen"
+#define URL_LISTEN_PREFIX "/listen/"
+
+#define MIME_HTML "text/html; charset=utf-8"
+#define MIME_TEXT "text/plain; charset=utf-8"
+#define MIME_CSS "text/css"
+
+#define HTML_HEADER(t)                                                  \
+    "<?xml version=\"1.0\"?>\n"                                         \
+    "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" \
+    "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"                   \
+    "        <head>\n"                                                  \
+    "                <title>"t"</title>\n"                              \
+    "                <link rel=\"stylesheet\" type=\"text/css\" href=\"style\"/>\n" \
+    "        </head>\n"                                                 \
+    "        <body>\n"
+
+#define HTML_FOOTER                                                     \
+    "        </body>\n"                                                 \
+    "</html>\n"
+enum state {
+    STATE_REQUEST_LINE,
+    STATE_MIME_HEADER,
+    STATE_DATA
+};
 
 struct connection {
     pa_http_protocol *protocol;
     pa_ioline *line;
-    enum {
-        REQUEST_LINE,
-        MIME_HEADER,
-        DATA
-    } state;
+    enum state state;
     char *url;
     pa_module *module;
 };
@@ -67,45 +86,242 @@ struct pa_http_protocol {
     pa_idxset *connections;
 };
 
-static void http_response(struct connection *c, int code, const char *msg, const char *mime) {
-    char s[256];
+
+static pa_bool_t is_mime_sample_spec(const pa_sample_spec *ss, const pa_channel_map *cm) {
+
+    pa_assert(pa_channel_map_compatible(cm, ss));
+
+    switch (ss->format) {
+        case PA_SAMPLE_S16BE:
+        case PA_SAMPLE_S24BE:
+        case PA_SAMPLE_U8:
+
+            if (ss->rate != 8000 &&
+                ss->rate != 11025 &&
+                ss->rate != 16000 &&
+                ss->rate != 22050 &&
+                ss->rate != 24000 &&
+                ss->rate != 32000 &&
+                ss->rate != 44100 &&
+                ss->rate != 48000)
+                return FALSE;
+
+            if (ss->channels != 1 &&
+                ss->channels != 2)
+                return FALSE;
+
+            if ((cm->channels == 1 && cm->map[0] != PA_CHANNEL_POSITION_MONO) ||
+                (cm->channels == 2 && (cm->map[0] != PA_CHANNEL_POSITION_LEFT || cm->map[1] != PA_CHANNEL_POSITION_RIGHT)))
+                return FALSE;
+
+            return TRUE;
+
+        case PA_SAMPLE_ULAW:
+
+            if (ss->rate != 8000)
+                return FALSE;
+
+            if (ss->channels != 1)
+                return FALSE;
+
+            if (cm->map[0] != PA_CHANNEL_POSITION_MONO)
+                return FALSE;
+
+            return TRUE;
+
+        default:
+            return FALSE;
+    }
+}
+
+static void mimefy_sample_spec(pa_sample_spec *ss, pa_channel_map *cm) {
+
+    pa_assert(pa_channel_map_compatible(cm, ss));
+
+    /* Turns the sample type passed in into the next 'better' one that
+     * can be encoded for HTTP. If there is no 'better' one we pick
+     * the 'best' one that is 'worse'. */
+
+    if (ss->channels > 2)
+        ss->channels = 2;
+
+    if (ss->rate > 44100)
+        ss->rate = 48000;
+    else if (ss->rate > 32000)
+        ss->rate = 44100;
+    else if (ss->rate > 24000)
+        ss->rate = 32000;
+    else if (ss->rate > 22050)
+        ss->rate = 24000;
+    else if (ss->rate > 16000)
+        ss->rate = 22050;
+    else if (ss->rate > 11025)
+        ss->rate = 16000;
+    else if (ss->rate > 8000)
+        ss->rate = 11025;
+    else
+        ss->rate = 8000;
+
+    switch (ss->format) {
+        case PA_SAMPLE_S24BE:
+        case PA_SAMPLE_S24LE:
+        case PA_SAMPLE_S24_32LE:
+        case PA_SAMPLE_S24_32BE:
+        case PA_SAMPLE_S32LE:
+        case PA_SAMPLE_S32BE:
+        case PA_SAMPLE_FLOAT32LE:
+        case PA_SAMPLE_FLOAT32BE:
+            ss->format = PA_SAMPLE_S24BE;
+            break;
+
+        case PA_SAMPLE_S16BE:
+        case PA_SAMPLE_S16LE:
+            ss->format = PA_SAMPLE_S16BE;
+            break;
+
+        case PA_SAMPLE_ULAW:
+        case PA_SAMPLE_ALAW:
+
+            if (ss->rate == 8000 && ss->channels == 1)
+                ss->format = PA_SAMPLE_ULAW;
+            else
+                ss->format = PA_SAMPLE_S16BE;
+            break;
+
+        case PA_SAMPLE_U8:
+            ss->format = PA_SAMPLE_U8;
+            break;
+
+        case PA_SAMPLE_MAX:
+        case PA_SAMPLE_INVALID:
+            pa_assert_not_reached();
+    }
+
+    pa_channel_map_init_auto(cm, ss->channels, PA_CHANNEL_MAP_DEFAULT);
+
+    pa_assert(is_mime_sample_spec(ss, cm));
+}
+
+static char *sample_spec_to_mime_type(const pa_sample_spec *ss, const pa_channel_map *cm) {
+    pa_assert(pa_channel_map_compatible(cm, ss));
+
+    if (!is_mime_sample_spec(ss, cm))
+        return NULL;
+
+    switch (ss->format) {
+
+        case PA_SAMPLE_S16BE:
+        case PA_SAMPLE_S24BE:
+        case PA_SAMPLE_U8:
+            return pa_sprintf_malloc("audio/%s; rate=%u; channels=%u",
+                                     ss->format == PA_SAMPLE_S16BE ? "L16" :
+                                     (ss->format == PA_SAMPLE_S24BE ? "L24" : "L8"),
+                                     ss->rate, ss->channels);
+
+        case PA_SAMPLE_ULAW:
+            return pa_xstrdup("audio/basic");
+
+        default:
+            pa_assert_not_reached();
+    }
+
+    pa_assert(pa_sample_spec_valid(ss));
+}
+
+static char *mimefy_and_stringify_sample_spec(const pa_sample_spec *_ss, const pa_channel_map *_cm) {
+    pa_sample_spec ss = *_ss;
+    pa_channel_map cm = *_cm;
+
+    mimefy_sample_spec(&ss, &cm);
+
+    return sample_spec_to_mime_type(&ss, &cm);
+}
+
+static char *escape_html(const char *t) {
+    pa_strbuf *sb;
+    const char *p, *e;
+
+    sb = pa_strbuf_new();
+
+    for (e = p = t; *p; p++) {
+
+        if (*p == '>' || *p == '<' || *p == '&') {
+
+            if (p > e) {
+                pa_strbuf_putsn(sb, e, p-e);
+                e = p + 1;
+            }
+
+            if (*p == '>')
+                pa_strbuf_puts(sb, "&gt;");
+            else if (*p == '<')
+                pa_strbuf_puts(sb, "&lt;");
+            else
+                pa_strbuf_puts(sb, "&amp;");
+        }
+    }
+
+    if (p > e)
+        pa_strbuf_putsn(sb, e, p-e);
+
+    return pa_strbuf_tostring_free(sb);
+}
+
+static void http_response(
+        struct connection *c,
+        int code,
+        const char *msg,
+        const char *mime) {
+
+    char *s;
 
     pa_assert(c);
     pa_assert(msg);
     pa_assert(mime);
 
-    pa_snprintf(s, sizeof(s),
-             "HTTP/1.0 %i %s\n"
-             "Connection: close\n"
-             "Content-Type: %s\n"
-             "Cache-Control: no-cache\n"
-             "Expires: 0\n"
-             "Server: "PACKAGE_NAME"/"PACKAGE_VERSION"\n"
-             "\n", code, msg, mime);
-
+    s = pa_sprintf_malloc(
+            "HTTP/1.0 %i %s\n"
+            "Connection: close\n"
+            "Content-Type: %s\n"
+            "Cache-Control: no-cache\n"
+            "Expires: 0\n"
+            "Server: "PACKAGE_NAME"/"PACKAGE_VERSION"\n"
+            "\n", code, msg, mime);
     pa_ioline_puts(c->line, s);
+    pa_xfree(s);
 }
 
-static void http_message(struct connection *c, int code, const char *msg, const char *text) {
-    char s[256];
+static void html_response(
+        struct connection *c,
+        int code,
+        const char *msg,
+        const char *text) {
+
+    char *s;
     pa_assert(c);
 
-    http_response(c, code, msg, "text/html");
+    http_response(c, code, msg, MIME_HTML);
 
     if (!text)
         text = msg;
 
-    pa_snprintf(s, sizeof(s),
-             "<?xml version=\"1.0\"?>\n"
-             "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
-             "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>%s</title></head>\n"
-             "<body>%s</body></html>\n",
-             text, text);
+    s = pa_sprintf_malloc(
+            HTML_HEADER("%s")
+            "%s"
+            HTML_FOOTER,
+            text, text);
 
     pa_ioline_puts(c->line, s);
+    pa_xfree(s);
+
     pa_ioline_defer_close(c->line);
 }
 
+static void internal_server_error(struct connection *c) {
+    pa_assert(c);
+
+    html_response(c, 500, "Internal Server Error", NULL);
+}
 
 static void connection_unlink(struct connection *c) {
     pa_assert(c);
@@ -113,12 +329,153 @@ static void connection_unlink(struct connection *c) {
     if (c->url)
         pa_xfree(c->url);
 
+    if (c->line)
+        pa_ioline_unref(c->line);
+
     pa_idxset_remove_by_data(c->protocol->connections, c, NULL);
 
-    pa_ioline_unref(c->line);
     pa_xfree(c);
 }
 
+static void html_print_field(pa_ioline *line, const char *left, const char *right) {
+    char *eleft, *eright;
+
+    eleft = escape_html(left);
+    eright = escape_html(right);
+
+    pa_ioline_printf(line,
+                     "<tr><td><b>%s</b></td>"
+                     "<td>%s</td></tr>\n", eleft, eright);
+
+    pa_xfree(eleft);
+    pa_xfree(eright);
+}
+
+static void handle_url(struct connection *c) {
+    pa_assert(c);
+
+    pa_log_debug("Request for %s", c->url);
+
+    if (pa_streq(c->url, URL_ROOT)) {
+        char *t;
+
+        http_response(c, 200, "OK", MIME_HTML);
+
+        pa_ioline_puts(c->line,
+                       HTML_HEADER(PACKAGE_NAME" "PACKAGE_VERSION)
+                       "<h1>"PACKAGE_NAME" "PACKAGE_VERSION"</h1>\n"
+                       "<table>\n");
+
+        t = pa_get_user_name_malloc();
+        html_print_field(c->line, "User Name:", t);
+        pa_xfree(t);
+
+        t = pa_get_host_name_malloc();
+        html_print_field(c->line, "Host name:", t);
+        pa_xfree(t);
+
+        t = pa_machine_id();
+        html_print_field(c->line, "Machine ID:", t);
+        pa_xfree(t);
+
+        t = pa_uname_string();
+        html_print_field(c->line, "System:", t);
+        pa_xfree(t);
+
+        t = pa_sprintf_malloc("%lu", (unsigned long) getpid());
+        html_print_field(c->line, "Process ID:", t);
+        pa_xfree(t);
+
+        pa_ioline_puts(c->line,
+                       "</table>\n"
+                       "<p><a href=\"/status\">Show an extensive server status report</a></p>\n"
+                       "<p><a href=\"/listen\">Monitor sinks and sources</a></p>\n"
+                       HTML_FOOTER);
+
+        pa_ioline_defer_close(c->line);
+
+    } else if (pa_streq(c->url, URL_CSS)) {
+        http_response(c, 200, "OK", MIME_CSS);
+
+        pa_ioline_puts(c->line,
+                       "body { color: black; background-color: white; }\n"
+                       "a:link, a:visited { color: #900000; }\n"
+                       "div.news-date { font-size: 80%; font-style: italic; }\n"
+                       "pre { background-color: #f0f0f0; padding: 0.4cm; }\n"
+                       ".grey { color: #8f8f8f; font-size: 80%; }"
+                       "table {  margin-left: 1cm; border:1px solid lightgrey; padding: 0.2cm; }\n"
+                       "td { padding-left:10px; padding-right:10px; }\n");
+
+        pa_ioline_defer_close(c->line);
+
+    } else if (pa_streq(c->url, URL_STATUS)) {
+        char *r;
+
+        http_response(c, 200, "OK", MIME_TEXT);
+        r = pa_full_status_string(c->protocol->core);
+        pa_ioline_puts(c->line, r);
+        pa_xfree(r);
+
+        pa_ioline_defer_close(c->line);
+
+    } else if (pa_streq(c->url, URL_LISTEN)) {
+        pa_source *source;
+        pa_sink *sink;
+        uint32_t idx;
+
+        http_response(c, 200, "OK", MIME_HTML);
+
+        pa_ioline_puts(c->line,
+                       HTML_HEADER("Listen")
+                       "<h2>Sinks</h2>\n"
+                       "<p>\n");
+
+        PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
+            char *t, *m;
+
+            t = escape_html(pa_strna(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+            m = mimefy_and_stringify_sample_spec(&sink->sample_spec, &sink->channel_map);
+
+            pa_ioline_printf(c->line,
+                             "<a href=\"/listen/%s\" title=\"%s\">%s</a><br/>\n",
+                             sink->monitor_source->name, m, t);
+
+            pa_xfree(t);
+            pa_xfree(m);
+        }
+
+        pa_ioline_puts(c->line,
+                       "</p>\n"
+                       "<h2>Sources</h2>\n"
+                       "<p>\n");
+
+        PA_IDXSET_FOREACH(source, c->protocol->core->sources, idx) {
+            char *t, *m;
+
+            if (source->monitor_of)
+                continue;
+
+            t = escape_html(pa_strna(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+            m = mimefy_and_stringify_sample_spec(&source->sample_spec, &source->channel_map);
+
+            pa_ioline_printf(c->line,
+                             "<a href=\"/listen/%s\" title=\"%s\">%s</a><br/>\n",
+                             source->name, m, t);
+
+            pa_xfree(m);
+            pa_xfree(t);
+
+        }
+
+        pa_ioline_puts(c->line,
+                       "</p>\n"
+                       HTML_FOOTER);
+
+        pa_ioline_defer_close(c->line);
+    } else
+        html_response(c, 404, "Not Found", NULL);
+}
+
 static void line_callback(pa_ioline *line, const char *s, void *userdata) {
     struct connection *c = userdata;
     pa_assert(line);
@@ -131,93 +488,27 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
     }
 
     switch (c->state) {
-        case REQUEST_LINE: {
-            if (memcmp(s, "GET ", 4))
+        case STATE_REQUEST_LINE: {
+            if (!pa_startswith(s, "GET "))
                 goto fail;
 
             s +=4;
 
             c->url = pa_xstrndup(s, strcspn(s, " \r\n\t?"));
-            c->state = MIME_HEADER;
+            c->state = STATE_MIME_HEADER;
             break;
-
         }
 
-        case MIME_HEADER: {
+        case STATE_MIME_HEADER: {
 
             /* Ignore MIME headers */
             if (strcspn(s, " \r\n") != 0)
                 break;
 
             /* We're done */
-            c->state = DATA;
-
-            pa_log_info("request for %s", c->url);
-
-            if (!strcmp(c->url, URL_ROOT)) {
-                char txt[256];
-                pa_sink *def_sink;
-                pa_source *def_source;
-                http_response(c, 200, "OK", "text/html");
-
-                pa_ioline_puts(c->line,
-                               "<?xml version=\"1.0\"?>\n"
-                               "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
-                               "<html xmlns=\"http://www.w3.org/1999/xhtml\"><title>"PACKAGE_NAME" "PACKAGE_VERSION"</title>\n"
-                               "<link rel=\"stylesheet\" type=\"text/css\" href=\"style\"/></head><body>\n");
-
-                pa_ioline_puts(c->line,
-                               "<h1>"PACKAGE_NAME" "PACKAGE_VERSION"</h1>\n"
-                               "<table>");
-
-#define PRINTF_FIELD(a,b) pa_ioline_printf(c->line, "<tr><td><b>%s</b></td><td>%s</td></tr>\n",(a),(b))
-
-                PRINTF_FIELD("User Name:", pa_get_user_name(txt, sizeof(txt)));
-                PRINTF_FIELD("Host name:", pa_get_host_name(txt, sizeof(txt)));
-                PRINTF_FIELD("Default Sample Specification:", pa_sample_spec_snprint(txt, sizeof(txt), &c->protocol->core->default_sample_spec));
-
-                def_sink = pa_namereg_get_default_sink(c->protocol->core);
-                def_source = pa_namereg_get_default_source(c->protocol->core);
-
-                PRINTF_FIELD("Default Sink:", def_sink ? def_sink->name : "n/a");
-                PRINTF_FIELD("Default Source:", def_source ? def_source->name : "n/a");
-
-                pa_ioline_puts(c->line, "</table>");
-
-                pa_ioline_puts(c->line, "<p><a href=\"/status\">Click here</a> for an extensive server status report.</p>");
-
-                pa_ioline_puts(c->line, "</body></html>\n");
-
-                pa_ioline_defer_close(c->line);
-            } else if (!strcmp(c->url, URL_CSS)) {
-                http_response(c, 200, "OK", "text/css");
-
-                pa_ioline_puts(c->line,
-                               "body { color: black; background-color: white; margin: 0.5cm; }\n"
-                               "a:link, a:visited { color: #900000; }\n"
-                               "p { margin-left: 0.5cm; margin-right: 0.5cm; }\n"
-                               "h1 { color: #00009F; }\n"
-                               "h2 { color: #00009F; }\n"
-                               "ul { margin-left: .5cm; }\n"
-                               "ol { margin-left: .5cm; }\n"
-                               "pre { margin-left: .5cm; background-color: #f0f0f0; padding: 0.4cm;}\n"
-                               ".grey { color: #afafaf; }\n"
-                               "table {  margin-left: 1cm; border:1px solid lightgrey; padding: 0.2cm; }\n"
-                               "td { padding-left:10px; padding-right:10px;  }\n");
-
-                pa_ioline_defer_close(c->line);
-            } else if (!strcmp(c->url, URL_STATUS)) {
-                char *r;
-
-                http_response(c, 200, "OK", "text/plain");
-                r = pa_full_status_string(c->protocol->core);
-                pa_ioline_puts(c->line, r);
-                pa_xfree(r);
-
-                pa_ioline_defer_close(c->line);
-            } else
-                http_message(c, 404, "Not Found", NULL);
+            c->state = STATE_DATA;
 
+            handle_url(c);
             break;
         }
 
@@ -247,7 +538,7 @@ void pa_http_protocol_connect(pa_http_protocol *p, pa_iochannel *io, pa_module *
     c = pa_xnew(struct connection, 1);
     c->protocol = p;
     c->line = pa_ioline_new(io);
-    c->state = REQUEST_LINE;
+    c->state = STATE_REQUEST_LINE;
     c->url = NULL;
     c->module = m;
 
@@ -258,12 +549,12 @@ void pa_http_protocol_connect(pa_http_protocol *p, pa_iochannel *io, pa_module *
 
 void pa_http_protocol_disconnect(pa_http_protocol *p, pa_module *m) {
     struct connection *c;
-    void *state = NULL;
+    uint32_t idx;
 
     pa_assert(p);
     pa_assert(m);
 
-    while ((c = pa_idxset_iterate(p->connections, &state, NULL)))
+    PA_IDXSET_FOREACH(c, p->connections, idx)
         if (c->module == m)
             connection_unlink(c);
 }

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list