]> code.delx.au - pulseaudio/blob - src/module-protocol-stub.c
fix modargs memory leak
[pulseaudio] / src / module-protocol-stub.c
1 #include <string.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <assert.h>
5 #include <arpa/inet.h>
6 #include <unistd.h>
7
8 #include "module.h"
9 #include "socket-server.h"
10 #include "socket-util.h"
11 #include "util.h"
12 #include "modargs.h"
13
14 #ifdef USE_PROTOCOL_SIMPLE
15 #include "protocol-simple.h"
16 #define protocol_new pa_protocol_simple_new
17 #define protocol_free pa_protocol_simple_free
18 #define IPV4_PORT 4711
19 #define UNIX_SOCKET "/tmp/polypaudio/simple"
20 #define MODULE_ARGUMENTS "rate", "format", "channels", "sink", "source", "playback", "record",
21 #else
22 #ifdef USE_PROTOCOL_CLI
23 #include "protocol-cli.h"
24 #define protocol_new pa_protocol_cli_new
25 #define protocol_free pa_protocol_cli_free
26 #define IPV4_PORT 4712
27 #define UNIX_SOCKET "/tmp/polypaudio/cli"
28 #define MODULE_ARGUMENTS
29 #else
30 #ifdef USE_PROTOCOL_NATIVE
31 #include "protocol-native.h"
32 #define protocol_new pa_protocol_native_new
33 #define protocol_free pa_protocol_native_free
34 #define IPV4_PORT 4713
35 #define UNIX_SOCKET "/tmp/polypaudio/native"
36 #define MODULE_ARGUMENTS "public", "cookie",
37 #else
38 #ifdef USE_PROTOCOL_ESOUND
39 #include "protocol-esound.h"
40 #include "esound-spec.h"
41 #define protocol_new pa_protocol_esound_new
42 #define protocol_free pa_protocol_esound_free
43 #define IPV4_PORT ESD_DEFAULT_PORT
44 #define UNIX_SOCKET ESD_UNIX_SOCKET_NAME
45 #define MODULE_ARGUMENTS "sink", "source", "public", "cookie",
46 #else
47 #error "Broken build system"
48 #endif
49 #endif
50 #endif
51 #endif
52
53 static const char* const valid_modargs[] = {
54 MODULE_ARGUMENTS
55 #ifdef USE_TCP_SOCKETS
56 "port",
57 "loopback",
58 #else
59 "socket",
60 #endif
61 NULL
62 };
63
64 struct pa_socket_server *create_socket_server(struct pa_core *c, struct pa_modargs *ma) {
65 struct pa_socket_server *s;
66 #ifdef USE_TCP_SOCKETS
67 uint32_t loopback = 0, port = IPV4_PORT;
68
69 if (pa_modargs_get_value_u32(ma, "loopback", &loopback) < 0) {
70 fprintf(stderr, "loopback= expects a numerical argument.\n");
71 return NULL;
72 }
73
74 if (pa_modargs_get_value_u32(ma, "port", &port) < 0) {
75 fprintf(stderr, "port= expects a numerical argument.\n");
76 return NULL;
77 }
78
79 if (!(s = pa_socket_server_new_ipv4(c->mainloop, loopback ? INADDR_LOOPBACK : INADDR_ANY, port)))
80 return NULL;
81 #else
82 int r;
83 const char *p;
84
85 p = pa_modargs_get_value(ma, "socket", UNIX_SOCKET);
86 assert(p);
87
88 if (pa_unix_socket_make_secure_dir(p) < 0) {
89 fprintf(stderr, "Failed to create secure socket directory.\n");
90 return NULL;
91 }
92
93 if ((r = pa_unix_socket_remove_stale(p)) < 0) {
94 fprintf(stderr, "Failed to remove stale UNIX socket '%s': %s\n", p, strerror(errno));
95 return NULL;
96 }
97
98 if (r)
99 fprintf(stderr, "Removed stale UNIX socket '%s'.", p);
100
101 if (!(s = pa_socket_server_new_unix(c->mainloop, p)))
102 return NULL;
103
104 #endif
105 return s;
106 }
107
108 int pa_module_init(struct pa_core *c, struct pa_module*m) {
109 struct pa_socket_server *s;
110 struct pa_modargs *ma = NULL;
111 int ret = -1;
112 assert(c && m);
113
114 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
115 fprintf(stderr, "Failed to parse module arguments\n");
116 goto finish;
117 }
118
119 if (!(s = create_socket_server(c, ma)))
120 goto finish;
121
122 if (!(m->userdata = protocol_new(c, s, m, ma))) {
123 pa_socket_server_free(s);
124 goto finish;
125 }
126
127 ret = 0;
128
129 finish:
130 if (ma)
131 pa_modargs_free(ma);
132
133 return ret;
134 }
135
136 void pa_module_done(struct pa_core *c, struct pa_module*m) {
137 assert(c && m);
138
139 protocol_free(m->userdata);
140 }