source: roaraudio/roard/req.c @ 443:e4ad581b8c09

Last change on this file since 443:e4ad581b8c09 was 443:e4ad581b8c09, checked in by phi, 16 years ago

got UNIX cred code working (ignoring them on non UNIX sockets)

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