source: roaraudio/roard/req.c @ 441:3748177846de

Last change on this file since 441:3748177846de was 441:3748177846de, checked in by phi, 16 years ago

we need to give getsockopt() a pointe rto the length, not the langth itself

File size: 11.6 KB
Line 
1//req.c:
2
3#include "roard.h"
4
5int req_on_noop        (int client, struct roar_message * mes, char * data) {
6 mes->cmd     = ROAR_CMD_OK;
7 mes->datalen = 0;
8 return 0;
9}
10
11int req_on_identify    (int client, struct roar_message * mes, char * data) {
12 struct roar_client * c;
13 int max_len;
14#ifdef SO_PEERCRED
15 struct ucred cred;
16 socklen_t cred_len = sizeof(cred);
17#endif
18
19 if ( mes->datalen < 1 )
20  return -1;
21
22 clients_get(client, &c);
23
24 if ( mes->data[0] == 1 ) {
25#ifdef SO_PEERCRED
26  if (getsockopt(c->fh, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len) != -1) {
27   c->pid = cred.pid;
28   c->uid = cred.uid;
29   c->gid = cred.gid;
30  } else {
31   ROAR_DBG("req_on_identify(): Can't get creds via SO_PEERCRED: %s", strerror(errno));
32  }
33#endif
34  if ( c->pid == -1 ) {
35   c->pid       = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1));
36  }
37
38  max_len = (mes->datalen - 5) < (ROAR_BUFFER_NAME-1) ? (mes->datalen - 5) : (ROAR_BUFFER_NAME-1);
39
40  strncpy(c->name, mes->data + 5, max_len);
41  c->name[max_len] = 0;
42
43  mes->cmd     = ROAR_CMD_OK;
44  mes->datalen = 0;
45
46  ROAR_DBG("req_on_identify(*): client=%i, pid=%i", client, c->pid);
47  ROAR_DBG("req_on_identify(*) = 0");
48  return 0;
49 }
50
51 return -1;
52}
53
54int req_on_auth        (int client, struct roar_message * mes, char * data) {
55 // TODO: add code to support some auth.
56 mes->cmd     = ROAR_CMD_OK;
57 mes->datalen = 0;
58 return 0;
59}
60
61
62int req_on_new_stream  (int client, struct roar_message * mes, char * data) {
63 int stream;
64 struct roar_stream * s;
65
66 if ((stream = streams_new()) == -1 )
67  return -1;
68
69 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
70  streams_delete(stream);
71  return -1;
72 }
73
74 if ( client_stream_add(client, stream) == -1 ) {
75  streams_delete(stream);
76  return -1;
77 }
78
79 if ( roar_stream_m2s(s, mes) == -1 ) {
80  streams_delete(stream);
81  return -1;
82 }
83
84 mes->cmd     = ROAR_CMD_OK;
85 mes->stream  = stream;
86 mes->datalen = 0;
87
88 return 0;
89}
90
91int req_on_exec_stream (int client, struct roar_message * mes, char * data) {
92 int r;
93
94 if ( (r = client_stream_exec(client, mes->stream)) == -1 )
95  return -1;
96
97 mes->cmd     = ROAR_CMD_OK;
98 mes->datalen = 0;
99
100 return 0;
101}
102
103int req_on_con_stream  (int client, struct roar_message * mes, char * data) {
104 char   host[80] = {0};
105 int    port = 0;
106 int    type;
107 int    fh;
108 int    len;
109
110 if ( mes->datalen < 4 )
111  return -1;
112
113 if ( *(mes->data) != 0 )
114  return -1;
115
116 if ( mes->datalen > 80 ) // we do not support long messages here
117  return -1;
118
119 type = (unsigned)mes->data[1];
120 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
121
122 len = mes->datalen - 4;
123
124 strncpy(host, &(mes->data[4]), len);
125 host[len] = 0;
126
127 if ( type > ROAR_SOCKET_TYPE_MAX )
128  return -1;
129
130 if ( type == ROAR_SOCKET_TYPE_FILE ) // disabled because of security resons
131  return -1;
132
133 if ( type == ROAR_SOCKET_TYPE_FORK ) // why should we connect to ourself?
134  return -1;
135
136 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
137  return -1;
138
139 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
140  close(fh);
141  return 1;
142 }
143
144 return 0;
145
146 mes->datalen = 0;
147 mes->cmd     = ROAR_CMD_OK;
148}
149
150
151int req_on_set_meta    (int client, struct roar_message * mes, char * data) {
152 int type;
153 int mode;
154 int namelen, vallen;
155 char   val[255+1];
156 char   name[ROAR_META_MAX_NAMELEN+1];
157
158 if ( mes->datalen < 3 )
159  return -1;
160
161 if ( mes->data[0] != 0 ) // version
162  return -1;
163
164 mode = (unsigned) mes->data[1];
165 type = (unsigned) mes->data[2];
166
167 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
168
169 if ( mode == ROAR_META_MODE_CLEAR ) {
170  stream_meta_clear(mes->stream);
171  mes->datalen = 0;
172  mes->cmd     = ROAR_CMD_OK;
173  return 0;
174 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
175 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
176  if ( mes->datalen < 5 )
177   return -1;
178
179  namelen = (unsigned) mes->data[3];
180  vallen  = (unsigned) mes->data[4];
181
182  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
183
184  if ( mes->datalen < (5 + namelen + vallen) )
185   return -1;
186
187  if ( namelen > ROAR_META_MAX_NAMELEN )
188   return -1;
189
190  strncpy(name, &(mes->data[5]), namelen);
191  name[namelen] = 0;
192
193  if ( vallen > 255 )
194   return -1;
195
196  strncpy(val, &(mes->data[5+namelen]), vallen);
197  val[vallen] = 0;
198
199  if ( mode == ROAR_META_MODE_SET ) {
200   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
201    return -1;
202  } else {
203   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
204    return -1;
205  }
206
207  mes->datalen = 0;
208  mes->cmd     = ROAR_CMD_OK;
209  return 0;
210 } else { // unknown mode!
211  return -1;
212 }
213
214 return -1;
215}
216
217int req_on_get_meta    (int client, struct roar_message * mes, char * data) {
218 int vallen;
219 int type;
220 char val[LIBROAR_BUFFER_MSGDATA-1];
221
222 if ( mes->datalen != 2 )
223  return -1;
224
225 if ( mes->data[0] != 0 ) // version
226  return -1;
227
228 type = (unsigned) mes->data[1];
229
230 if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 )
231  return -1;
232
233 vallen = strlen(val);
234
235 mes->cmd     = ROAR_CMD_OK;
236 mes->datalen = 2 + vallen;
237
238 mes->data[0] = 0;
239 mes->data[1] = (unsigned char) vallen;
240
241 val[vallen] = 0;
242
243 strncpy(&(mes->data[2]), val, vallen+1);
244
245 return 0;
246}
247
248int req_on_list_meta   (int client, struct roar_message * mes, char * data) {
249 int i;
250 int len = 0;
251 int types[ROAR_META_MAX_PER_STREAM];
252
253 if ( mes->datalen != 1 )
254  return -1;
255
256 if ( mes->data[0] != 0 ) // version
257  return -1;
258
259 if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 )
260  return -1;
261
262 mes->cmd     = ROAR_CMD_OK;
263 mes->datalen = 1 + len;
264 mes->data[0] = 0;
265
266 for (i = 0; i < len; i++)
267  mes->data[i+1] = types[i];
268
269 return 0;
270}
271
272int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
273 struct roar_stream s;
274//ROAR_DIR_OUTPUT
275
276 s.dir           = ROAR_DIR_OUTPUT;
277 s.pos_rel_id    = -1;
278 s.info.rate     = g_sa->rate;
279 s.info.bits     = g_sa->bits;
280 s.info.channels = g_sa->channels;
281 s.info.codec    = g_sa->codec;
282
283 if ( roar_stream_s2m(&s, mes) == -1 )
284  return -1;
285
286 mes->cmd = ROAR_CMD_OK;
287
288 return 0;
289}
290
291
292int req_on_get_standby (int client, struct roar_message * mes, char * data) {
293 mes->cmd = ROAR_CMD_OK;
294 mes->datalen = 2;
295
296 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
297
298 return 0;
299}
300
301int req_on_set_standby (int client, struct roar_message * mes, char * data) {
302 if ( mes->datalen != 2 )
303  return -1;
304
305 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
306
307 mes->cmd     = ROAR_CMD_OK;
308 mes->datalen = 0;
309
310 return 0;
311}
312
313int req_on_exit      (int client, struct roar_message * mes, char * data) {
314 mes->cmd     = ROAR_CMD_OK;
315 mes->datalen = 0;
316
317 alive = 0;
318
319 return 0;
320}
321
322int req_on_list_clients(int client, struct roar_message * mes, char * data) {
323 unsigned char filter, cmp;
324 uint32_t id;
325 int clients[ROAR_CLIENTS_MAX];
326 int i, c = 0;
327
328 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
329  return -1;
330
331 // TODO: add code to support filter
332 if ( filter != ROAR_CTL_FILTER_ANY )
333  return -1;
334
335 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
336  if ( g_clients[i] != NULL ) {
337   clients[c++] = i;
338  }
339 }
340
341 roar_ctl_ia2m(mes, clients, c);
342
343 mes->cmd = ROAR_CMD_OK;
344
345 return 0;
346}
347int req_on_list_streams(int client, struct roar_message * mes, char * data) {
348 unsigned char filter, cmp;
349 uint32_t id;
350 int streams[ROAR_STREAMS_MAX];
351 int i, c = 0;
352
353 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
354  return -1;
355
356 // TODO: add code to support filter
357 if ( filter != ROAR_CTL_FILTER_ANY )
358  return -1;
359
360 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
361  if ( g_streams[i] != NULL ) {
362   streams[c++] = i;
363  }
364 }
365
366 roar_ctl_ia2m(mes, streams, c);
367
368 mes->cmd = ROAR_CMD_OK;
369
370 return 0;
371}
372
373int req_on_get_client  (int client, struct roar_message * mes, char * data) {
374 struct roar_client * c;
375
376 if ( mes->datalen != 1 )
377  return -1;
378
379 if ( clients_get(mes->data[0], &c) == -1 )
380  return -1;
381
382 mes->cmd = ROAR_CMD_OK;
383
384 return roar_ctl_c2m(mes, c);
385}
386
387int req_on_get_stream  (int client, struct roar_message * mes, char * data) {
388 struct roar_stream_server * s;
389
390 if ( mes->datalen != 1 )
391  return -1;
392
393 if ( streams_get(mes->data[0], &s) == -1 )
394  return -1;
395
396 mes->cmd = ROAR_CMD_OK;
397
398 return roar_stream_s2m(ROAR_STREAM(s), mes);
399}
400
401int req_on_kick (int client, struct roar_message * mes, char * data) {
402 uint16_t * info = (uint16_t *) mes->data;
403
404 if ( mes->datalen != 4 )
405  return -1;
406
407 info[0] = ROAR_NET2HOST16(info[0]);
408 info[1] = ROAR_NET2HOST16(info[1]);
409
410 if ( info[0] == ROAR_OT_CLIENT ) {
411  clients_delete(info[1]);
412 } else if ( info[0] == ROAR_OT_STREAM ) {
413  streams_delete(info[1]);
414 } else {
415  return -1;
416 }
417
418 mes->cmd     = ROAR_CMD_OK;
419 mes->datalen = 0;
420
421 return 0;
422}
423
424int req_on_set_vol (int client, struct roar_message * mes, char * data) {
425 uint16_t * info = (uint16_t *) mes->data;
426 int stream;
427 struct roar_stream_server * s;
428 int i;
429 int chans;
430
431 ROAR_DBG("req_on_set_vol(*) = ?");
432 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
433
434 if ( mes->datalen < (4*2) )
435  return -1;
436
437 if ( info[0] != 0 ) // version
438  return -1;
439
440 stream = ROAR_NET2HOST16(info[1]);
441 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
442
443 // TODO: change this code.
444 //       we should not directly change the stream object but use some stream_*()-func
445 //       for that job.
446
447 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
448  return -1;
449
450 s = g_streams[stream];
451
452 if ( s == NULL )
453  return -1;
454
455 ROAR_DBG("req_on_set_vol(*): s=%p", s);
456
457 info[2] = ROAR_NET2HOST16(info[2]);
458
459 if ( info[2] == ROAR_SET_VOL_ALL ) {
460  chans = (mes->datalen/2) - 3;
461  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
462
463  if ( chans >= ROAR_MAX_CHANNELS )
464   return -1;
465
466  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
467
468  for (i = 0; i < chans; i++) {
469   s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]);
470   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3]));
471  }
472
473  ROAR_DBG("req_on_set_vol(*): mixer changed!");
474
475 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
476  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
477  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
478   return -1;
479
480  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
481 } else {
482  return -1;
483 }
484
485 mes->cmd     = ROAR_CMD_OK;
486 mes->datalen = 0;
487
488 return 0;
489}
490
491int req_on_get_vol (int client, struct roar_message * mes, char * data) {
492 uint16_t * info = (uint16_t *) mes->data;
493 int stream;
494 struct roar_stream_server * s;
495 int i;
496 int chans;
497
498 ROAR_DBG("req_on_get_vol(*) = ?");
499 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
500
501 if ( mes->datalen < (2*2) )
502  return -1;
503
504 if ( info[0] != 0 ) // version
505  return -1;
506
507 stream = ROAR_NET2HOST16(info[1]);
508 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
509
510 // TODO: change this code.
511 //       we should not directly change the stream object but use some stream_*()-func
512 //       for that job.
513
514 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
515  return -1;
516
517 s = g_streams[stream];
518
519 if ( s == NULL )
520  return -1;
521
522 ROAR_DBG("req_on_get_vol(*): s=%p", s);
523
524 // ok, we have everything
525
526 info[0] = 0;
527 info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
528
529 for (i = 0; i < chans; i++)
530  info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
531
532 mes->datalen = (2 + chans)*2;
533 mes->cmd = ROAR_CMD_OK;
534
535 return 0;
536}
537
538int req_on_add_data (int client, struct roar_message * mes, char * data) {
539 struct roar_buffer * b;
540 char               * buf;
541
542 if ( roar_buffer_new(&b, mes->datalen) == -1 ) {
543  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
544  ROAR_DBG("req_on_add_data(*) = -1");
545  return -1;
546 }
547
548 roar_buffer_get_data(b, (void **)&buf);
549
550 if ( data == NULL ) {
551  memcpy(buf, mes->data, mes->datalen);
552 } else {
553  memcpy(buf, data, mes->datalen);
554 }
555
556 if ( stream_add_buffer(mes->stream, b) == -1 ) {
557  roar_buffer_free(b);
558  return -1;
559 }
560
561 mes->cmd     = ROAR_CMD_OK;
562 mes->datalen = 0;
563
564 return 0;
565}
566
567//ll
Note: See TracBrowser for help on using the repository browser.