source: roaraudio/roard/roard.c @ 2451:e6aedd121ada

Last change on this file since 2451:e6aedd121ada was 2451:e6aedd121ada, checked in by phi, 15 years ago

init/free ssynth

File size: 34.7 KB
RevLine 
[0]1//roard.c:
2
[668]3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
[0]25#include "roard.h"
26
[1494]27#ifdef ROAR_SUPPORT_LISTEN
[60]28char * server = ROAR_DEFAULT_SOCK_GLOBAL; // global server address
[1494]29#endif
[60]30
[2104]31#if defined(ROAR_HAVE_IO_POSIX) && defined(ROAR_HAVE_FS_POSIX)
32#define SUPPORT_PIDFILE
33char * pidfile = NULL;
34#endif
35
[1503]36#ifdef ROAR_HAVE_MAIN_ARGS
[0]37void usage (void) {
38 printf("Usage: roard [OPTIONS]...\n\n");
39
[68]40 printf("Misc Options:\n\n");
41 printf(
[775]42        " --daemon              - Bring the server into background after init\n"
[71]43        " --terminate           - Terminate after last client quited\n"
[2109]44        " --start               - No op parameter (starting roard is default operation)\n"
[274]45        " --restart             - Trys to stop an old instance and start a new with new settings\n"
[2109]46        " --stop                - Stops a running roard (provide --pidfile!)\n"
47        " --shutdown            - Terminates a running roard (provide --pidfile!)\n"
[276]48        " --realtime            - Trys to get realtime priority,\n"
49        "                         give multible times for being more realtime\n"
[444]50        " --chroot DIR          - chroots to the given dir\n"
51        " --setgid              - GroupID to the audio group as specified via -G\n"
52        " --setuid              - UserID to the audio user as specified via -U\n"
[905]53        " --sysclocksync        - calculate exact sample rate using the system clock\n"
[2017]54        " --location  LOC       - Set lion readable location of server\n"
[2104]55#ifdef SUPPORT_PIDFILE
56        " --pidfile PIDFILE     - Write a pidfile at PIDFILE\n"
57#endif
[68]58       );
59
60 printf("\nAudio Options:\n\n");
[0]61 printf(
62        " -R  --rate   RATE     - Set server rate\n"
63        " -B  --bits   BITS     - Set server bits\n"
64        " -C  --chans  CHANNELS - Set server channels\n"
65       );
66
[2339]67 printf("\nStream Options:\n\n");
68 printf(
69        " --stream-flags D=F    - Set default flags for stream directions\n"
70        "                         D is the stream direction and F is a comma seperated\n"
71        "                         list of flags in form +flag or -flag to set or unset\n"
72        "                         a flag as default or remove it from the default\n"
73       );
74
[1923]75 printf("\nDriver Options: (obsolete, do not use, Use Ouput Options)\n\n");
[974]76 printf(" -d  --driver DRV      - Set the driver (default: %s)\n", ROAR_DRIVER_DEFAULT);
[0]77 printf(" -D  --device DEV      - Set the device\n");
78 printf(" -dO OPTS              - Set output options\n");
[973]79 printf(" --list-driver         - List all drivers\n");
[0]80
[932]81 printf("\nOutput Options:\n\n");
[974]82 printf(" -o  --odriver DRV     - Set the driver, use '--list-driver' to get a list\n");
[932]83 printf(" -O  --odevice DEV     - Set the device\n");
84 printf(" -oO OPTS              - Set output options\n");
85 printf(" -oN                   - Adds another output\n");
[961]86 printf(" -oP                   - Mark output as primary\n");
[932]87
[0]88 printf("\nSource Options:\n\n");
89 printf(" -s  --source DRV      - Use DRV as input driver\n"
90        " -S           DEV      - Use DEV as input device\n"
91        " -sO          OPTS     - Use OPTS as input options\n"
[1512]92        " -sN                   - Adds another source\n"
[0]93        " -sP                   - Make souce as primary\n"
94       );
[2270]95 printf(" --list-sources        - List all sources\n");
[0]96
[280]97 printf("\nCodec Filter Options:\n\n");
98 printf(" --list-cf             - List all codec filter\n"
99       );
[0]100
[1923]101 printf("\nMIDI Options:\n\n");
[1924]102 printf(" --midi-no-console     - Disable console based MIDI synth\n"
[2444]103        " --midi-console-enable - Enables the console based MIDI synth\n"
[1924]104        " --midi-console DEV    - Set device for MIDI console\n"
[2451]105        " --ssynth-enable       - Enable simple software synth\n"
106        " --ssynth-disable      - Disable simple software synth\n"
[1924]107       );
[1923]108
109 printf("\nLight Control Options:\n\n");
110 printf(" --light-channels NUM  - Sets the number of channels for Light control (default: %i)\n",
111                                  LIGHT_CHANNELS_DEFAULT
112       );
113
[0]114 printf("\nServer Options:\n\n");
115 printf(" -t  --tcp             - Use TCP listen socket\n"
116        " -u  --unix            - Use UNIX Domain listen socket (default)\n"
[508]117#ifdef ROAR_HAVE_LIBDNET
118        " -n  --decnet          - use DECnet listen socket\n"
119#endif
[518]120        " -4                    - Use IPv4 connections (implies -t)\n"
121#ifdef PF_INET6
122        " -6                    - Use IPv6 connections (implies -t)\n"
123#endif
124#ifdef IPV6_ADDRFORM
125        " -64                   - Try to downgrade sockets from IPv6 into IPv4,\n"
126        "                         this is normaly not usefull.\n"
127#endif
[0]128        " -p  --port            - TCP Port to bind to\n"
129        " -b  --bind            - IP/Hostname to bind to\n"
[1115]130        "     --sock            - Filename for UNIX Domain Socket\n"
[1993]131#ifdef ROAR_HAVE_LIBSLP
132        "     --slp             - Enable OpenSLP support\n"
133#endif
[450]134        " -G  GROUP             - Sets the group for the UNIX Domain Socket, (default: %s)\n"
[60]135        "                         You need the permittions to change the GID\n"
[444]136        " -U  USER              - Sets the user for the UNIX Domain Socket, (default: do not set)\n"
137        "                         You need the permittions to change the UID (normaly only root has)\n"
[548]138        " --no-listen           - Do not listen for new clients\n"
139        "                         (only usefull for relaing, impleys --terminate)\n"
[274]140        " --client-fh           - Comunicate with a client over this handle\n"
[501]141        "                         (only usefull for relaing)\n"
[920]142        " --close-fh            - Closes the given fh\n"
143        " --standby             - Start in standby state\n"
144        " --auto-standby        - Automatical goes into standby if there are no streams\n",
[450]145        ROAR_DEFAULT_SOCKGRP
[0]146       );
147// printf("\n Options:\n\n");
148 printf("\n");
149}
[1503]150#endif
[0]151
[2109]152int restart_server (char * server, int terminate) {
[579]153 struct roar_connection con;
[2111]154#ifdef ROAR_HAVE_KILL
155 char buf[80];
156 ssize_t l;
157 struct roar_vio_calls fh;
158 pid_t pid;
159 int ok;
160
161 if ( pidfile != NULL ) {
162  if ( roar_vio_open_file(&fh, pidfile, O_RDONLY, 0644) == -1 ) {
163   ROAR_WARN("restart_server(*): Can not read pidfile: %s", pidfile);
164  } else {
165   l = roar_vio_read(&fh, buf, 80);
166   roar_vio_close(&fh);
167   if ( l > 0 ) {
168    buf[l-1] = 0;
169    buf[79]  = 0;
170    pid = atoi(buf);
171    if ( terminate ) {
[2113]172     ok = kill(pid, SIGUSR1);
[2111]173    } else {
174     ok = kill(pid, SIGINT);
175    }
176    if ( ok == 0 ) {
177     return 0;
178    } else {
179     ROAR_WARN("restart_server(*): Can not kill roard by pidfile");
180    }
181   } else {
182    ROAR_WARN("restart_server(*): Can not find a PID in the pidfile");
183   }
184  }
185 }
186#endif
[2109]187
[579]188 if ( roar_connect(&con, server) == -1 ) {
189  return -1;
190 }
191
[2109]192 if ( roar_terminate(&con, terminate) == -1 ) {
[579]193  return -1;
194 }
195
196 return roar_disconnect(&con);
197}
198
[444]199#define R_SETUID 1
200#define R_SETGID 2
201
[1609]202int init_config (void) {
203 int i;
204
205 memset(g_config, 0, sizeof(struct roard_config));
206
207 for (i = 0; i < ROAR_DIR_DIRIDS; i++) {
208  g_config->streams[i].mixer_channels = 1;
209  g_config->streams[i].mixer.rpg_mul  = 1;
210  g_config->streams[i].mixer.rpg_div  = 1;
211  g_config->streams[i].mixer.scale    = 65535;
212  g_config->streams[i].mixer.mixer[0] = g_config->streams[i].mixer.scale;
213 }
214
[2291]215 g_config->streams[ROAR_DIR_PLAY    ].flags = ROAR_FLAG_META;
[2413]216 g_config->streams[ROAR_DIR_OUTPUT  ].flags = ROAR_FLAG_PASSMIXER;
[2264]217 g_config->streams[ROAR_DIR_FILTER  ].flags = ROAR_FLAG_SYNC;
[1899]218 g_config->streams[ROAR_DIR_MIDI_OUT].flags = ROAR_FLAG_SYNC;
[2160]219 g_config->streams[ROAR_DIR_BIDIR   ].flags = ROAR_FLAG_ANTIECHO;
[1899]220
[2017]221 g_config->location = "***default***";
222
[1609]223 return 0;
224}
225
[2339]226int update_stream_flags (char * str) {
227 int    dir;
228 char * flags;
229 char * k;
230 int    op;
231 int    flag;
232
233 if ( (flags = strstr(str, "=")) == NULL )
234  return -1;
235
236 *flags = 0;
237  flags++;
238
239 if ( (dir = roar_str2dir(str)) == -1 )
240  return -1;
241
242 while (flags != NULL) {
243  k = flags;
244  flags = strstr(flags, ",");
245
246  if ( flags != NULL )
247   *(flags++) = 0;
248
249  switch (*k) {
[2340]250   case '+': k++; op = ROAR_SET_FLAG;   break;
251   case '-': k++; op = ROAR_RESET_FLAG; break;
[2339]252   default:
[2340]253     op = ROAR_SET_FLAG;
[2339]254  }
255
256  flag = 0;
257
258  if ( !strcmp(k, "sync") ) {
259   flag = ROAR_FLAG_SYNC;
260  } else if ( !strcmp(k, "meta") ) {
261   flag = ROAR_FLAG_META;
262  } else if ( !strcmp(k, "cleanmeta") ) {
263   flag = ROAR_FLAG_CLEANMETA;
264  } else if ( !strcmp(k, "pause") ) {
265   flag = ROAR_FLAG_PAUSE;
266  } else if ( !strcmp(k, "mute") ) {
267   flag = ROAR_FLAG_MUTE;
268  } else if ( !strcmp(k, "antiecho") ) {
269   flag = ROAR_FLAG_ANTIECHO;
[2413]270  } else if ( !strcmp(k, "passmixer") ) {
271   flag = ROAR_FLAG_PASSMIXER;
[2339]272  } else {
273   return -1;
274  }
275
276  g_config->streams[dir].flags |= flag;
277
[2340]278  if ( op == ROAR_RESET_FLAG )
[2339]279   g_config->streams[dir].flags -= flag;
280 }
281
282 return 0;
283}
284
[1145]285int add_output (char * drv, char * dev, char * opts, int prim, int count) {
[933]286 int stream;
287 struct roar_stream * s;
288 struct roar_stream_server * ss;
[938]289 char * k, * v;
[1208]290#ifdef ROAR_DRIVER_CODEC
291 char * to_free = NULL;
292#endif
[938]293 int codec;
[1926]294 int sync = 0, f_mmap = 0;
[1522]295 int32_t blocks = -1, blocksize = -1;
[1920]296 int dir = ROAR_DIR_OUTPUT;
[1991]297 int error = 0;
298 // DMX:
299 int32_t channel  = -1;
300 int32_t universe = -1;
301 uint16_t tu16;
[2085]302 float q = -32e6;
[933]303
[938]304 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
[933]305
[1145]306 if ( drv == NULL && count == 0 ) {
307  drv  = ROAR_DRIVER_DEFAULT;
308  prim = 1;
309  sync = 1;
[1208]310
311#ifdef ROAR_DRIVER_CODEC
312  if ( opts == NULL ) {
313   opts = to_free = strdup("codec=" ROAR_DRIVER_CODEC);
314  }
315#endif
[1145]316 }
317
[1227]318 if ( opts == NULL && count == 0 ) {
319  sync = 1;
320  prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 1
321 }
322
[933]323 if ( (stream = streams_new()) == -1 ) {
[938]324  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
[982]325  if ( prim ) alive = 0;
[933]326  return -1;
327 }
328
329 streams_get(stream, &ss);
330 s = ROAR_STREAM(ss);
331
332 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
333
334 s->pos_rel_id = -1;
335// s->info.codec = codec;
336
[938]337 codec = s->info.codec;
338
339 k = strtok(opts, ",");
340 while (k != NULL) {
341//  ROAR_WARN("add_output(*): opts: %s", k);
342
343  if ( (v = strstr(k, "=")) != NULL ) {
344   *v++ = 0;
345  }
346
347  ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v);
348  if ( strcmp(k, "rate") == 0 ) {
349   s->info.rate = atoi(v);
350  } else if ( strcmp(k, "channels") == 0 ) {
351   s->info.channels = atoi(v);
352  } else if ( strcmp(k, "bits") == 0 ) {
353   s->info.bits = atoi(v);
354  } else if ( strcmp(k, "codec") == 0 ) {
355   if ( (codec = roar_str2codec(v)) == -1 ) {
356    ROAR_ERR("add_output(*): unknown codec '%s'", v);
[1991]357    error++;
[938]358   }
[2085]359  } else if ( strcmp(k, "q") == 0 ) {
360   q = atof(v);
[1221]361  } else if ( strcmp(k, "blocks") == 0 ) {
362   blocks = atoi(v);
[1522]363  } else if ( strcmp(k, "blocksize") == 0 ) {
364   blocksize = atoi(v);
[1926]365  } else if ( strcmp(k, "mmap") == 0 ) {
366   f_mmap = 1;
[1919]367  } else if ( strcmp(k, "subsystem") == 0 ) {
368   if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) {
[1920]369    dir = ROAR_DIR_OUTPUT;
[1919]370   } else if ( !strcasecmp(v, "midi") ) {
371    dir = ROAR_DIR_MIDI_OUT;
372   } else if ( !strcasecmp(v, "light") ) {
373    dir = ROAR_DIR_LIGHT_OUT;
[2234]374   } else if ( !strcasecmp(v, "raw") ) {
375    dir = ROAR_DIR_RAW_OUT;
[1919]376   } else {
377    ROAR_ERR("add_output(*): unknown subsystem '%s'", k);
[1991]378    error++;
379   }
380  // DMX:
381  } else if ( strcmp(k, "channel") == 0 ) {
382   channel  = atoi(v);
383   if ( channel < 0 || channel > 65535 ) {
384    ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel);
385    channel = -1;
386    error++;
[1919]387   }
[1991]388  } else if ( strcmp(k, "universe") == 0 ) {
389   universe = atoi(v);
390   if ( universe < 0 || universe > 255 ) {
391    ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe);
392    universe = -1;
393    error++;
394   }
395
[2115]396  } else if ( strcmp(k, "name") == 0 ) {
397   if ( streams_set_name(stream, v) == -1 ) {
398    ROAR_ERR("add_output(*): Can not set Stream name");
399    error++;
400   }
[1991]401
[1032]402  } else if ( strcmp(k, "meta") == 0 ) {
403   streams_set_flag(stream, ROAR_FLAG_META);
[1117]404  } else if ( strcmp(k, "sync") == 0 ) {
405   sync = 1;
[1221]406  } else if ( strcmp(k, "primary") == 0 ) {
407   prim = 1;
408
409  } else if ( strcmp(k, "cleanmeta") == 0 ) {
410   streams_set_flag(stream, ROAR_FLAG_CLEANMETA);
411  } else if ( strcmp(k, "autoconf") == 0 ) {
[1531]412   streams_set_flag(stream, ROAR_FLAG_AUTOCONF);
[2413]413  } else if ( strcmp(k, "recsource") == 0 ) {
414   streams_set_flag(stream, ROAR_FLAG_RECSOURCE);
415  } else if ( strcmp(k, "passmixer") == 0 ) {
416   streams_set_flag(stream, ROAR_FLAG_PASSMIXER);
[938]417  } else {
418   ROAR_ERR("add_output(*): unknown option '%s'", k);
[1991]419   error++;
420  }
421
422  if ( error ) {
[938]423   streams_delete(stream);
[982]424   if ( prim ) alive = 0;
[1208]425#ifdef ROAR_DRIVER_CODEC
426   if ( to_free != NULL )
427    free(to_free);
428#endif
[938]429   return -1;
430  }
431
432  k = strtok(NULL, ",");
433 }
434
[1919]435 if ( streams_set_dir(stream, dir, 1) == -1 ) {
436  streams_delete(stream);
437  return -1;
438 }
439
[1208]440#ifdef ROAR_DRIVER_CODEC
441 if ( to_free != NULL )
442  free(to_free);
443#endif
444
[941]445 if ( codec == ROAR_CODEC_ALAW || codec == ROAR_CODEC_MULAW )
446  s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter
447
[938]448 s->info.codec = codec;
449 ROAR_STREAM_SERVER(s)->codec_orgi = codec;
[933]450
[2364]451 if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) {
[1581]452  ss->driver_id = -1; // don't close a driver not opened...
453  memset(&(ss->vio), 0, sizeof(struct roar_vio_calls));
[933]454  streams_delete(stream);
[938]455  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
[982]456  if ( prim ) alive = 0;
[933]457  return -1;
458 }
459
[1528]460 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here
461 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM,   s); // ignore errors here
462
[1221]463 if ( blocks != -1 )
464  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks);
465
[1522]466 if ( blocksize != -1 )
467  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize);
468
[1991]469 // TODO: we shoudld *really* check for errors here...
470 if ( channel != -1 ) {
471  tu16 = channel;
472  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16);
473 }
474 if ( universe != -1 ) {
475  tu16 = universe;
476  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16);
477 }
478
[1156]479 ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id);
480
[938]481 streams_set_fh(stream, -1); // update some internal structures
482
[2087]483 if ( q > -1e6 ) {
484  ROAR_DBG("add_output(*): setting q=%f", q);
485  streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q);
486 }
487
[933]488 client_stream_add(g_source_client, stream);
489
[1200]490 if ( prim ) {
[961]491  streams_mark_primary(stream);
[1200]492  s->pos_rel_id = stream;
493 }
[961]494
[1120]495 if ( sync ) {
[1117]496  streams_set_flag(stream, ROAR_FLAG_SYNC);
[1120]497 } else {
498  streams_reset_flag(stream, ROAR_FLAG_SYNC);
499 }
[1117]500
[1926]501 if ( f_mmap )
502  streams_set_flag(stream, ROAR_FLAG_MMAP);
503
[933]504 return 0;
[932]505}
506
[1993]507
508// SLP:
509void register_slp_callback(SLPHandle hslp, SLPError errcode, void * cookie) {
510 /* return the error code in the cookie */
511 *(SLPError*)cookie = errcode;
512}
513
514int register_slp (int unreg, char * sockname) {
515#ifdef ROAR_HAVE_LIBSLP
516 static int regged = 0;
517 static char * sn = NULL;
518 SLPError err;
519 SLPError callbackerr;
520 SLPHandle hslp;
521 char addr[1024];
522 char attr[1024] = "";
[2017]523 char * location;
[1993]524
525 if ( sockname != NULL )
526  sn = sockname;
527
[2016]528 snprintf(addr, sizeof(addr), ROAR_SLP_URL_TYPE "://%s", sn);
[1993]529
530 err = SLPOpen("en", SLP_FALSE, &hslp);
531
532 if (err != SLP_OK) {
533  ROAR_ERR("Error opening slp handle: Error #%i", err);
534  return -1;
535 }
536
537 if (!unreg) {
[2017]538
539  if ( SLPEscape(g_config->location, &location, SLP_FALSE) != SLP_OK ) {
540   ROAR_ERR("Error using SLPEscape() on server location, really bad!");
541   SLPClose(hslp);
542   return -1;
543  }
544
[1995]545  snprintf(attr, sizeof(attr), "(wave-rate=%i),(wave-channels=%i),(wave-bits=%i),"
[2017]546                               "(light-channels=%i),(location=%s)",
[1995]547           g_sa->rate, g_sa->channels, g_sa->bits,
[2017]548           g_light_state.channels,
549           location
[1995]550          );
551
[1993]552  /* Register a service with SLP */
553  err = SLPReg(hslp,
554               addr,
555               SLP_LIFETIME_MAXIMUM,
556               0,
557               attr,
558               SLP_TRUE,
559               register_slp_callback,
560               &callbackerr);
[1994]561  regged = 1;
562 } else if ( unreg && regged ) {
563  err = SLPDereg(hslp, addr, register_slp_callback, &callbackerr);
564  regged = 0;
565 } else {
566  SLPClose(hslp);
567  return -1;
568 }
[1993]569
[1994]570 /* err may contain an error code that occurred as the slp library    */
571 /* _prepared_ to make the call.                                     */
572 if ( err != SLP_OK ) {
573  ROAR_ERR("Error (de)registering service with slp: Error #%i", err);
574  return -1;
575 }
576
577 /* callbackerr may contain an error code (that was assigned through */
578 /* the callback cookie) that occurred as slp packets were sent on    */
579 /* the wire */
580 if (callbackerr != SLP_OK) {
581  ROAR_ERR("Error (de)registering service with slp: Error #%i", callbackerr);
582  return -1;
[1993]583 }
584
585 SLPClose(hslp);
586 return 0;
587#else
588 return -1;
589#endif
590}
591
592
593// MAIN:
594
[1503]595#ifdef ROAR_HAVE_MAIN_ARGS
[0]596int main (int argc, char * argv[]) {
[1503]597#else
598int main (void) {
599#endif
600#ifdef ROAR_HAVE_MAIN_ARGS
[0]601 int i;
602 char * k;
[1503]603#endif
[1494]604#ifdef ROAR_SUPPORT_LISTEN
[905]605 char user_sock[80]  = {0};
[1494]606#endif
[1609]607 struct roar_audio_info sa, max_sa;
608 struct roard_config config;
[1486]609#ifdef ROAR_HAVE_FORK
[905]610 int    daemon       = 0;
[1486]611#endif
[905]612 int    realtime     = 0;
613 int    sysclocksync = 0;
[1207]614 char * driver    = NULL;
615 char * device    = NULL;
[1503]616#ifdef ROAR_HAVE_MAIN_ARGS
[1207]617 char * opts      = NULL;
[1503]618#endif
[60]619// char * server = ROAR_DEFAULT_SOCK_GLOBAL;
[1494]620#ifdef ROAR_SUPPORT_LISTEN
[1207]621 int      port    = ROAR_DEFAULT_PORT;
[1494]622#endif
[0]623 int               drvid;
[550]624 char * s_drv     = "cf";
[1110]625 char * s_dev     = NULL;
[444]626 char * s_con     = NULL;
627 char * s_opt     = NULL;
628 int    s_prim    = 0;
[1207]629 char * o_drv     = getenv("ROAR_DRIVER");
630 char * o_dev     = getenv("ROAR_DEVICE");
[932]631 char * o_opts    = NULL;
[961]632 int    o_prim    = 0;
[1145]633 int    o_count   = 0;
[1923]634 int    light_channels = LIGHT_CHANNELS_DEFAULT;
[450]635 char * sock_grp  = ROAR_DEFAULT_SOCKGRP;
[444]636 char * sock_user = NULL;
[1494]637#ifdef ROAR_SUPPORT_LISTEN
[517]638 int    sock_type = ROAR_SOCKET_TYPE_UNKNOWN;
[1494]639#endif
[1993]640#ifdef ROAR_HAVE_LIBSLP
641 int    reg_slp   = 0;
642#endif
[1486]643#ifdef ROAR_HAVE_CHROOT
[444]644 char * chrootdir = NULL;
[1486]645#endif
646#if defined(ROAR_HAVE_SETGID) || defined(ROAR_HAVE_SETUID)
[444]647 int    setids    = 0;
[1486]648#endif
649#ifdef ROAR_HAVE_UNIX
[1011]650 char * env_roar_proxy_backup;
[1486]651#endif
652#if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_IO_POSIX)
[446]653 struct group   * grp  = NULL;
[1486]654#endif
655#if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX)
[446]656 struct passwd  * pwd  = NULL;
[1486]657#endif
658#ifdef ROAR_HAVE_GETSERVBYNAME
[446]659 struct servent * serv = NULL;
[1486]660#endif
[0]661 DRIVER_USERDATA_T drvinst;
[39]662 struct roar_client * self = NULL;
[508]663#ifdef ROAR_HAVE_LIBDNET
664 char decnethost[80];
665#endif
[2104]666#ifdef SUPPORT_PIDFILE
667 struct roar_vio_calls pidfile_vio;
668#endif
[0]669
670 g_standby       =  0;
[920]671 g_autostandby   =  0;
[982]672 alive           =  1;
[1494]673#ifdef ROAR_SUPPORT_LISTEN
[1155]674 g_no_listen     =  0;
[1494]675 g_listen_socket = -1;
676#else
677 g_terminate     =  1;
678#endif
[0]679
680 sa.bits     = ROAR_BITS_DEFAULT;
681 sa.channels = ROAR_CHANNELS_DEFAULT;
682 sa.rate     = ROAR_RATE_DEFAULT;
683 sa.codec    = ROAR_CODEC_DEFAULT;
684
[1609]685 g_sa        = &sa;
686 g_max_sa    = &max_sa;
687
688 memcpy(g_max_sa, g_sa, sizeof(max_sa));
689
690 g_config = &config;
691
692 if ( init_config() == -1 ) {
693  ROAR_ERR("Can not init default config!");
694  return 1;
695 }
[0]696
[1924]697 if ( midi_init_config() == -1 ) {
698  ROAR_ERR("Can not init MIDI config!");
699  return 1;
700 }
[60]701
[2451]702 if ( ssynth_init_config() == -1 ) {
703  ROAR_ERR("Can not init ssynth config!");
704  return 1;
705 }
706
[1494]707#ifdef ROAR_SUPPORT_LISTEN
[1753]708#ifdef ROAR_HAVE_GETUID
[1486]709 if ( getuid() != 0 && getenv("HOME") != NULL ) {
710  snprintf(user_sock, 79, "%s/%s", (char*)getenv("HOME"), ROAR_DEFAULT_SOCK_USER);
[60]711  server = user_sock;
712 }
[1753]713#endif
[60]714
[279]715 if ( getenv("ROAR_SERVER") != NULL )
716  server = getenv("ROAR_SERVER");
[1494]717#endif
[279]718
[63]719 if ( clients_init() == -1 ) {
720  ROAR_ERR("Can not init clients!");
721  return 1;
722 }
723
724 if ( streams_init() == -1 ) {
725  ROAR_ERR("Can not init streams!");
726  return 1;
727 }
728
[64]729 if ( (g_self_client = clients_new()) == -1 ) {
730  ROAR_ERR("Can not create self client!");
731  return 1;
732 }
733
[0]734 if ( sources_init() == -1 ) {
735  ROAR_ERR("Can not init sources!");
736  return 1;
737 }
738
[64]739 if ( (sources_set_client(g_self_client)) == -1 ) {
740  ROAR_ERR("Can not init set source client!");
741  return 1;
742 }
743
[1503]744#ifdef ROAR_HAVE_MAIN_ARGS
[0]745 for (i = 1; i < argc; i++) {
746  k = argv[i];
747
748  if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) {
749   usage();
750   return 0;
751
[2109]752  } else if ( strcmp(k, "--start") == 0 ) {
753   // this is a no op
[579]754  } else if ( strcmp(k, "--restart") == 0 ) {
[1494]755#ifdef ROAR_SUPPORT_LISTEN
[2109]756   if ( restart_server(server, 1) == -1 ) {
[579]757    ROAR_WARN("Can not terminate old server (not running at %s?), tring to continue anyway", server);
758   }
[1494]759#else
760   ROAR_ERR("--restart not supported");
761#endif
[2109]762  } else if ( strcmp(k, "--shutdown") == 0 ) {
763#ifdef ROAR_SUPPORT_LISTEN
764   if ( restart_server(server, 1) == -1 ) {
765    ROAR_WARN("Can not terminate old server (not running at %s?)", server);
766    return 1;
767   }
768   return 0;
769#else
770   ROAR_ERR("--shutdown not supported");
771   return 1;
772#endif
773  } else if ( strcmp(k, "--stop") == 0 ) {
774#ifdef ROAR_SUPPORT_LISTEN
[2111]775   if ( restart_server(server, 0) == -1 ) {
[2109]776    ROAR_WARN("Can not stop old server (not running at %s?)", server);
777    return 1;
778   }
779   return 0;
780#else
781   ROAR_ERR("--stop not supported");
782   return 1;
783#endif
784
[579]785
[775]786  } else if ( strcmp(k, "--demon") == 0 || strcmp(k, "--daemon") == 0 ) {
[1486]787#ifdef ROAR_HAVE_FORK
[775]788   daemon = 1;
[1486]789#else
790   ROAR_ERR("--daemon not supported");
791#endif
[71]792  } else if ( strcmp(k, "--terminate") == 0 ) {
793   g_terminate = 1;
[905]794  } else if ( strcmp(k, "--sysclocksync") == 0 ) {
795   sysclocksync = 1000;
[275]796  } else if ( strcmp(k, "--realtime") == 0 ) {
[276]797   realtime++;
[444]798  } else if ( strcmp(k, "--chroot") == 0 ) {
[1486]799#ifdef ROAR_HAVE_CHROOT
[444]800   chrootdir = argv[++i];
[1486]801#else
802   ROAR_ERR("--chroot not supported");
803   i++;
804#endif
[444]805  } else if ( strcmp(k, "--setgid") == 0 ) {
[1486]806#ifdef ROAR_HAVE_SETGID
[444]807   setids |= R_SETGID;
[1486]808#else
809   ROAR_ERR("--setgid not supported");
810#endif
[444]811  } else if ( strcmp(k, "--setuid") == 0 ) {
[1486]812#ifdef ROAR_HAVE_SETUID
[444]813   setids |= R_SETUID;
[1486]814#else
815   ROAR_ERR("--setuid not supported");
816#endif
[2017]817  } else if ( strcmp(k, "--location") == 0 ) {
818   g_config->location = argv[++i];
[2104]819  } else if ( strcmp(k, "--pidfile") == 0 ) {
820#ifdef SUPPORT_PIDFILE
821   pidfile = argv[++i];
822#else
823   ROAR_ERR("--pidfile not supported");
824   i++;
825#endif
[68]826
[280]827  } else if ( strcmp(k, "--list-cf") == 0 ) {
828   print_codecfilterlist();
829   return 0;
830
[0]831  } else if ( strcmp(k, "-R") == 0 || strcmp(k, "--rate") == 0 ) {
832   sa.rate = atoi(argv[++i]);
833  } else if ( strcmp(k, "-B") == 0 || strcmp(k, "--bits") == 0 ) {
834   sa.bits = atoi(argv[++i]);
835  } else if ( strcmp(k, "-C") == 0 || strcmp(k, "--chans") == 0 ) {
836   sa.channels = atoi(argv[++i]);
837
[2339]838  } else if ( strcmp(k, "--stream-flags") == 0 ) {
839   if ( update_stream_flags(argv[++i]) == -1 ) {
840    ROAR_ERR("Can not set stream flags");
841    return 1;
842   }
843
[0]844  } else if ( strcmp(k, "-d") == 0 || strcmp(k, "--driver") == 0 ) {
845   driver = argv[++i];
846   if ( strcmp(driver, "list") == 0 ) {
[974]847    ROAR_WARN("The option is obsolete, use --list-driver!");
[0]848    print_driverlist();
[973]849    return 0;
[0]850   }
851  } else if ( strcmp(k, "-D") == 0 || strcmp(k, "--device") == 0 ) {
852   device = argv[++i];
853  } else if ( strcmp(k, "-dO") == 0 ) {
854   opts = argv[++i];
[973]855  } else if ( strcmp(k, "--list-driver") == 0 ) {
856   print_driverlist();
857   return 0;
[0]858
[932]859  } else if ( strcmp(k, "-o") == 0 || strcmp(k, "--odriver") == 0 ) {
860   o_drv  = argv[++i];
861  } else if ( strcmp(k, "-O") == 0 || strcmp(k, "--odevice") == 0 ) {
862   o_dev  = argv[++i];
863  } else if ( strcmp(k, "-oO") == 0 ) {
864   o_opts = argv[++i];
[961]865  } else if ( strcmp(k, "-oP") == 0 ) {
866   o_prim = 1;
[932]867  } else if ( strcmp(k, "-oN") == 0 ) {
[1145]868   if ( add_output(o_drv, o_dev, o_opts, o_prim, o_count) != -1 )
869    o_count++;
870
[961]871   o_drv  = o_dev = o_opts = NULL;
872   o_prim = 0;
[932]873
[0]874  } else if ( strcmp(k, "-s") == 0 || strcmp(k, "--source") == 0 ) {
[550]875   s_drv = argv[++i];
876  } else if ( strcmp(k, "-S") == 0 ) {
[1110]877   s_dev = argv[++i];
[0]878  } else if ( strcmp(k, "-sO") == 0 ) {
879   s_opt = argv[++i];
880  } else if ( strcmp(k, "-sC") == 0 ) {
881   s_con = argv[++i];
882  } else if ( strcmp(k, "-sP") == 0 ) {
883   s_prim = 1;
[1110]884  } else if ( strcmp(k, "-sN") == 0 ) {
885   if ( sources_add(s_drv, s_dev, s_con, s_opt, s_prim) == -1 ) {
886    ROAR_ERR("main(*): adding source '%s' via '%s' failed!", s_dev, s_drv);
887   }
888   s_opt = s_dev = s_con = NULL;
889   s_drv = "cf";
890   s_prim = 0;
[2270]891  } else if ( strcmp(k, "--list-sources") == 0 ) {
892   print_sourcelist();
893   return 0;
[0]894
[1923]895  } else if ( strcmp(k, "--light-channels") == 0 ) {
896   light_channels = atoi(argv[++i]);
897
[1924]898  } else if ( strcmp(k, "--midi-no-console") == 0 ) {
899   midi_config.init_cb = 0;
[2444]900  } else if ( strcmp(k, "--midi-console-enable") == 0 ) {
901   midi_config.init_cb = 1;
[1924]902  } else if ( strcmp(k, "--midi-console") == 0 ) {
903   midi_config.console_dev = argv[++i];
[2444]904   midi_config.init_cb = 1;
[1924]905
[2451]906  } else if ( strcmp(k, "--ssynth-enable") == 0 ) {
907   ssynth_conf.enable = 1;
908  } else if ( strcmp(k, "--ssynth-disable") == 0 ) {
909   ssynth_conf.enable = 0;
910
[0]911  } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--port") == 0 ) {
[447]912   // This is only usefull in INET not UNIX mode.
[1494]913#ifdef ROAR_SUPPORT_LISTEN
[447]914   if ( *server == '/' )
915    server = ROAR_DEFAULT_HOST;
916
[446]917   errno = 0;
918   if ( (port = atoi(argv[++i])) < 1 ) {
[1486]919#ifdef ROAR_HAVE_GETSERVBYNAME
[446]920    if ( (serv = getservbyname(argv[i], "tcp")) == NULL ) {
921     ROAR_ERR("Unknown service: %s: %s", argv[i], strerror(errno));
922     return 1;
923    }
924    // NOTE: we need to use ROAR_NET2HOST16() here even if s_port is of type int!
925    ROAR_DBG("main(*): serv = {s_name='%s', s_aliases={...}, s_port=%i, s_proto='%s'}",
926            serv->s_name, ROAR_NET2HOST16(serv->s_port), serv->s_proto);
927    port = ROAR_NET2HOST16(serv->s_port);
[1486]928#else
929    ROAR_ERR("invalite port number: %s", argv[i]);
930    return 1;
931#endif
[446]932   }
[1494]933#endif
[1115]934  } else if ( strcmp(k, "-b") == 0 || strcmp(k, "--bind") == 0 || strcmp(k, "--sock") == 0 ) {
[1494]935#ifdef ROAR_SUPPORT_LISTEN
[0]936   server = argv[++i];
[1494]937#endif
[518]938
[573]939  } else if ( strcmp(k, "-t") == 0 || strcmp(k, "--tcp") == 0 ) {
[1494]940#ifdef ROAR_SUPPORT_LISTEN
[518]941   if ( sock_type != ROAR_SOCKET_TYPE_TCP && sock_type != ROAR_SOCKET_TYPE_TCP6 )
942    sock_type = ROAR_SOCKET_TYPE_TCP;
943
944   if ( *server == '/' )
945    server = ROAR_DEFAULT_HOST;
[1494]946#endif
[518]947
948  } else if ( strcmp(k, "-4") == 0 ) {
[1494]949#ifdef ROAR_SUPPORT_LISTEN
[517]950   sock_type = ROAR_SOCKET_TYPE_TCP;
[447]951   if ( *server == '/' )
952    server = ROAR_DEFAULT_HOST;
[1494]953#endif
[518]954  } else if ( strcmp(k, "-6") == 0 ) {
[1494]955#ifdef ROAR_SUPPORT_LISTEN
[519]956#ifdef PF_INET6
[518]957   sock_type = ROAR_SOCKET_TYPE_TCP6;
958   if ( *server == '/' )
959    server = ROAR_DEFAULT_HOST;
[519]960#else
961    ROAR_ERR("No IPv6 support compiled in!");
962    return 1;
963#endif
[1494]964#endif
[518]965
[573]966  } else if ( strcmp(k, "-u") == 0 || strcmp(k, "--unix") == 0 ) {
[1494]967#ifdef ROAR_SUPPORT_LISTEN
[62]968   // ignore this case as it is the default behavor.
[517]969   sock_type = ROAR_SOCKET_TYPE_UNIX;
[1494]970#endif
[518]971
[573]972  } else if ( strcmp(k, "-n") == 0 || strcmp(k, "--decnet") == 0 ) {
[1494]973#ifdef ROAR_SUPPORT_LISTEN
[508]974#ifdef ROAR_HAVE_LIBDNET
975    port   = ROAR_DEFAULT_NUM;
976    strcpy(decnethost, ROAR_DEFAULT_LISTEN_OBJECT);
977    server = decnethost;
[517]978    sock_type = ROAR_SOCKET_TYPE_DECNET;
[508]979#else
980    ROAR_ERR("No DECnet support compiled in!");
981    return 1;
982#endif
[1494]983#endif
[518]984
[1993]985  } else if ( strcmp(k, "--slp") == 0 ) {
986#ifdef ROAR_HAVE_LIBSLP
987   reg_slp = 1;
988#else
989    ROAR_ERR("No OpenSLP support compiled in!");
990    return 1;
991#endif
992
[60]993  } else if ( strcmp(k, "-G") == 0 ) {
[444]994   sock_grp  = argv[++i];
995  } else if ( strcmp(k, "-U") == 0 ) {
996   sock_user = argv[++i];
[0]997
[68]998  } else if ( strcmp(k, "--no-listen") == 0 ) {
[1494]999#ifdef ROAR_SUPPORT_LISTEN
[1787]1000   server      = "";
[548]1001   g_terminate = 1;
[1155]1002   g_no_listen = 1;
[1494]1003#endif
[68]1004  } else if ( strcmp(k, "--client-fh") == 0 ) {
1005   if ( clients_set_fh(clients_new(), atoi(argv[++i])) == -1 ) {
1006    ROAR_ERR("main(*): Can not set client's fh");
1007    return 1;
1008   }
[501]1009  } else if ( strcmp(k, "--close-fh") == 0 ) {
[1486]1010#ifdef ROAR_HAVE_IO_POSIX
[501]1011   close(atoi(argv[++i]));
[1486]1012#else
1013   i++;
1014   ROAR_WARN("can not close file handle %s (closing not supported)", argv[i]);
1015#endif
[68]1016
[920]1017  } else if ( strcmp(k, "--standby") == 0 ) {
1018   g_standby = 1;
1019  } else if ( strcmp(k, "--auto-standby") == 0 ) {
1020   g_autostandby = 1;
[0]1021  } else {
1022   usage();
1023   return 1;
1024  }
1025
1026 }
[1503]1027#endif
[0]1028
[1110]1029 if ( s_dev != NULL ) {
1030  if ( sources_add(s_drv, s_dev, s_con, s_opt, s_prim) == -1 ) {
1031   ROAR_ERR("main(*): adding source '%s' via '%s' failed!", s_dev, s_drv);
1032  }
1033 }
1034
[1145]1035 add_output(o_drv, o_dev, o_opts, o_prim, o_count);
[932]1036
[0]1037 ROAR_DBG("Server config: rate=%i, bits=%i, chans=%i", sa.rate, sa.bits, sa.channels);
1038
[1819]1039 if ( midi_init() == -1 ) {
[281]1040  ROAR_ERR("Can not initialize MIDI subsystem");
[1819]1041 }
1042
[2451]1043 if ( ssynth_init() == -1 ) {
1044  ROAR_ERR("Can not initialize ssynth subsystem");
1045 }
1046
[1819]1047 if ( light_init(light_channels) == -1 ) {
1048  ROAR_ERR("Can not initialize light control subsystem");
1049 }
[281]1050
[1494]1051#ifdef ROAR_SUPPORT_LISTEN
[68]1052 if ( *server != 0 ) {
[517]1053  if ( (g_listen_socket = roar_socket_listen(sock_type, server, port)) == -1 ) {
[1486]1054#ifdef ROAR_HAVE_UNIX
[286]1055   if ( *server == '/' ) {
[1011]1056    if ( (env_roar_proxy_backup = getenv("ROAR_PROXY")) != NULL ) {
1057     env_roar_proxy_backup = strdup(env_roar_proxy_backup);
1058     unsetenv("ROAR_PROXY");
1059    }
[286]1060    if ( (i = roar_socket_connect(server, port)) != -1 ) {
1061     close(i);
1062     ROAR_ERR("Can not open listen socket!");
1063     return 1;
1064    } else {
1065     unlink(server);
[517]1066     if ( (g_listen_socket = roar_socket_listen(sock_type, server, port)) == -1 ) {
[286]1067      ROAR_ERR("Can not open listen socket!");
1068      return 1;
1069     }
1070    }
[1011]1071    if ( env_roar_proxy_backup != NULL ) {
1072     setenv("ROAR_PROXY", env_roar_proxy_backup, 0);
1073     free(env_roar_proxy_backup);
1074    }
[1486]1075#else
1076   if (0) { // noop
1077#endif
[286]1078   } else {
1079    ROAR_ERR("Can not open listen socket!");
1080    return 1;
1081   }
[68]1082  }
[0]1083
[1486]1084#if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_IO_POSIX)
[523]1085  if ( (grp = getgrnam(sock_grp)) == NULL ) {
1086   ROAR_ERR("Can not get GID for group %s: %s", sock_grp, strerror(errno));
1087  }
[1486]1088#endif
1089#if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX)
[523]1090  if ( sock_user || (setids & R_SETUID) ) {
1091   if ( (pwd = getpwnam(sock_user)) == NULL ) {
1092    ROAR_ERR("Can not get UID for user %s: %s", sock_user, strerror(errno));
1093   }
1094  }
[1486]1095#endif
[523]1096
[1516]1097#if defined(ROAR_HAVE_IO_POSIX) && defined(ROAR_HAVE_UNIX)
[68]1098  if ( *server == '/' ) {
[523]1099   if ( grp ) {
[444]1100    if ( pwd ) {
[1691]1101     if ( chown(server, pwd->pw_uid, grp->gr_gid) == -1 )
1102      return 1;
[444]1103    } else {
[1691]1104     if ( chown(server, -1, grp->gr_gid) == -1 )
1105      return 1;
[444]1106    }
[1753]1107#ifdef ROAR_HAVE_GETUID
[68]1108    if ( getuid() == 0 )
[1691]1109     if ( chmod(server, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1 )
1110      return 1;
[1753]1111#endif
[68]1112   }
[60]1113  }
[1486]1114#endif
[60]1115 }
[1494]1116#endif
[60]1117
[0]1118 if ( output_buffer_init(&sa) == -1 ) {
1119  ROAR_ERR("Can not init output buffer!");
1120  return 1;
1121 }
1122
[1145]1123 if ( driver == NULL ) {
1124  driver = "null";
1125 } else {
1126  ROAR_WARN("Usage of old driver interface. use -o not -d!");
1127 }
1128
[0]1129 if ( driver_open(&drvinst, &drvid, driver, device, &sa) == -1 ) {
1130  ROAR_ERR("Can not open output driver!");
1131  return 1;
1132 }
1133
[44]1134 if ( samples_init() == -1 ) {
1135  ROAR_ERR("Can not init samples!");
1136  return 1;
1137 }
1138
1139
[1486]1140 // we should handle this on microcontrollers, too.
[1753]1141#if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_TARGET_WIN32)
[0]1142 signal(SIGINT,  on_sig_int);
[285]1143 signal(SIGCHLD, on_sig_chld);
[2112]1144 signal(SIGUSR1, on_sig_usr1);
[0]1145 signal(SIGPIPE, SIG_IGN);  // ignore broken pipes
[1486]1146#endif
[0]1147
[275]1148 if ( realtime ) {
[278]1149#ifdef DEBUG
1150  ROAR_WARN("compiled with -DDEBUG but realtime is enabled: for real realtime support compiel without -DDEBUG");
1151#endif
1152
[1486]1153#ifdef ROAR_HAVE_NICE
[275]1154  errno = 0;
[276]1155  nice(-5*realtime); // -5 for each --realtime
[1486]1156  if ( errno ) {
1157   ROAR_WARN("Can not decrease nice value by %i: %s", 5*realtime, strerror(errno));
1158  }
1159#else
1160  ROAR_WARN("Can not decrease nice value by %i: %s", 5*realtime, strerror(errno));
1161#endif
[277]1162/*
[276]1163#ifdef __linux__
[277]1164  if ( ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0)) == -1 )
1165   ROAR_WARN("Can not set io priority: %s", strerror(errno));
[276]1166#endif
[277]1167*/
[275]1168 }
1169
[1486]1170#ifdef ROAR_HAVE_SETGID
[444]1171 if ( setids & R_SETGID ) {
1172  if ( setgroups(0, (const gid_t *) NULL) == -1 ) {
1173   ROAR_ERR("Can not clear supplementary group IDs: %s", strerror(errno));
1174  }
[523]1175  if ( !grp || setgid(grp->gr_gid) == -1 ) {
[444]1176   ROAR_ERR("Can not set GroupID: %s", strerror(errno));
1177  }
1178 }
[1486]1179#endif
[444]1180
[0]1181
[39]1182 clients_set_pid(g_self_client, getpid());
[1753]1183#ifdef ROAR_HAVE_GETUID
[440]1184 clients_set_uid(g_self_client, getuid());
[1753]1185#endif
1186#ifdef ROAR_HAVE_GETGID
[440]1187 clients_set_gid(g_self_client, getgid());
[1753]1188#endif
[39]1189 clients_get(g_self_client, &self);
[37]1190
[39]1191 if ( self == NULL ) {
1192  ROAR_ERR("Can not get self client!");
1193  return 1;
1194 }
1195
[775]1196 strcpy(self->name, "RoarAudio daemon internal");
[68]1197
[1486]1198#ifdef ROAR_HAVE_FORK
[775]1199 if ( daemon ) {
[68]1200  close(ROAR_STDIN );
1201  close(ROAR_STDOUT);
1202  close(ROAR_STDERR);
[1753]1203
[68]1204  if ( fork() )
[1486]1205   ROAR_U_EXIT(0);
[1753]1206
1207#ifdef ROAR_HAVE_SETSID
1208  setsid();
1209#endif
[1046]1210  clients_set_pid(g_self_client, getpid()); // reset pid as it changed
[68]1211 }
[1486]1212#endif
[68]1213
[2104]1214#ifdef SUPPORT_PIDFILE
[2106]1215 if ( pidfile != NULL ) {
1216  if ( roar_vio_open_file(&pidfile_vio, pidfile, O_WRONLY|O_CREAT, 0644) == -1 ) {
1217   ROAR_ERR("Can not write pidfile: %s", pidfile);
1218  } else {
1219   roar_vio_printf(&pidfile_vio, "%i\n", getpid());
1220   roar_vio_close(&pidfile_vio);
1221  }
[2104]1222 }
1223#endif
1224
[1486]1225#ifdef ROAR_HAVE_CHROOT
[444]1226 if (chrootdir) {
1227  if ( chroot(chrootdir) == -1 ) {
1228   ROAR_ERR("Can not chroot to %s: %s", chrootdir, strerror(errno));
1229   return 2;
1230  }
1231  if ( chdir("/") == -1 ) {
1232   ROAR_ERR("Can not chdir to /: %s", strerror(errno));
1233   return 2;
1234  }
1235 }
[1486]1236#endif
[444]1237
[1486]1238#ifdef ROAR_HAVE_SETUID
[444]1239 if ( setids & R_SETUID ) {
1240  if ( !pwd || setuid(pwd->pw_uid) == -1 ) {
1241   ROAR_ERR("Can not set UserID: %s", strerror(errno));
1242   return 3;
1243  }
[1753]1244#ifdef ROAR_HAVE_GETUID
[444]1245  clients_set_uid(g_self_client, getuid());
[1753]1246#endif
[444]1247 }
[1486]1248#endif
[444]1249
[1993]1250 // Register with OpenSLP:
[2028]1251#ifdef ROAR_HAVE_LIBSLP
[1993]1252 if ( reg_slp ) {
1253  register_slp(0, server);
1254 }
[2028]1255#endif
[1993]1256
[0]1257 // start main loop...
[905]1258 main_loop(drvid, drvinst, &sa, sysclocksync);
[0]1259
1260 // clean up.
1261 clean_quit_prep();
1262 driver_close(drvinst, drvid);
1263 output_buffer_free();
1264
1265 return 0;
1266}
1267
[574]1268void cleanup_listen_socket (int terminate) {
[1993]1269 // Deregister from SLP:
[2028]1270#ifdef ROAR_HAVE_LIBSLP
[1993]1271 register_slp(1, NULL);
[2028]1272#endif
[580]1273
[1494]1274#ifdef ROAR_SUPPORT_LISTEN
[580]1275 if ( g_listen_socket != -1 ) {
[1486]1276#ifdef ROAR_HAVE_IO_POSIX
[580]1277  close(g_listen_socket);
[1486]1278#endif // #else is useless because we are in void context.
[60]1279
[580]1280  g_listen_socket = -1;
[576]1281
[1486]1282#ifdef ROAR_HAVE_UNIX
[580]1283  if ( *server == '/' )
1284   unlink(server);
[1486]1285#endif
[580]1286 }
[60]1287
[1494]1288#endif
1289
[574]1290 if ( terminate )
1291  g_terminate = 1;
1292}
1293
1294void clean_quit_prep (void) {
1295 cleanup_listen_socket(0);
[60]1296
[0]1297 sources_free();
1298 streams_free();
1299 clients_free();
[2451]1300 ssynth_free();
[282]1301 midi_cb_stop(); // stop console beep
[281]1302 midi_free();
[1819]1303 light_free();
[2104]1304
1305#ifdef SUPPORT_PIDFILE
1306 if ( pidfile != NULL )
1307  unlink(pidfile);
1308#endif
[0]1309}
1310
1311void clean_quit (void) {
1312 clean_quit_prep();
1313// driver_close(drvinst, drvid);
1314// output_buffer_free();
1315 exit(0);
1316}
1317
1318//ll
Note: See TracBrowser for help on using the repository browser.