Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
muted.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * Updated for Mac OSX CoreAudio
9  * by Josh Roberson <josh@asteriasgi.com>
10  *
11  * See http://www.asterisk.org for more information about
12  * the Asterisk project. Please do not directly contact
13  * any of the maintainers of this project for assistance;
14  * the project provides a web site, mailing lists and IRC
15  * channels for your use.
16  *
17  * This program is free software, distributed under the terms of
18  * the GNU General Public License Version 2. See the LICENSE file
19  * at the top of the source tree.
20  */
21 
22 /*! \file
23  *
24  * \brief Mute Daemon
25  *
26  * \author Mark Spencer <markster@digium.com>
27  *
28  * Updated for Mac OSX CoreAudio
29  * \arg Josh Roberson <josh@asteriasgi.com>
30  *
31  * \note Specially written for Malcolm Davenport, but I think I'll use it too
32  * Connects to the Asterisk Manager Interface, AMI, and listens for events
33  * on certain devices. If a phone call is connected to one of the devices (phones)
34  * the local sound is muted to a lower volume during the call.
35  *
36  */
37 
38 /*! \li \ref muted.c uses the configuration file \ref muted.conf
39  * \addtogroup configuration_file Configuration Files
40  */
41 
42 /*!
43  * \page muted.conf muted.conf
44  * \verbinclude muted.conf.sample
45  */
46 
47 /*** MODULEINFO
48  <support_level>deprecated</support_level>
49  ***/
50 
51 #include "asterisk/autoconfig.h"
52 
53 #ifdef __Darwin__
54 #include <CoreAudio/AudioHardware.h>
55 #include <sys/types.h>
56 #include <pwd.h>
57 #include <sys/stat.h>
58 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__GLIBC__)
59 #include <sys/soundcard.h>
60 #endif
61 #include <stdio.h>
62 #include <errno.h>
63 #include <stdlib.h>
64 #include <unistd.h>
65 #include <fcntl.h>
66 #include <string.h>
67 #include <netdb.h>
68 #include <sys/socket.h>
69 #include <sys/ioctl.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
72 
73 #define ast_strlen_zero(a) (!(*(a)))
74 
75 static char *config = "/etc/asterisk/muted.conf";
76 
77 static char host[256] = "";
78 static char user[256] = "";
79 static char pass[256] = "";
80 static int smoothfade = 0;
81 static int mutelevel = 20;
82 static int muted = 0;
83 static int needfork = 1;
84 static int debug = 0;
85 static int stepsize = 3;
86 #ifndef __Darwin__
87 static int mixchan = SOUND_MIXER_VOLUME;
88 #endif
89 
90 struct subchannel {
91  char *name;
92  struct subchannel *next;
93 };
94 
95 static struct channel {
96  char *tech;
97  char *location;
98  struct channel *next;
99  struct subchannel *subs;
100 } *channels;
101 
102 static void add_channel(char *tech, char *location)
103 {
104  struct channel *chan;
105  chan = malloc(sizeof(struct channel));
106  if (chan) {
107  memset(chan, 0, sizeof(struct channel));
108  if (!(chan->tech = strdup(tech))) {
109  free(chan);
110  return;
111  }
112  if (!(chan->location = strdup(location))) {
113  free(chan->tech);
114  free(chan);
115  return;
116  }
117  chan->next = channels;
118  channels = chan;
119  }
120 
121 }
122 
123 static int load_config(void)
124 {
125  FILE *f;
126  char buf[1024];
127  char *val;
128  char *val2;
129  int lineno=0;
130  int x;
131  f = fopen(config, "r");
132  if (!f) {
133  fprintf(stderr, "Unable to open config file '%s': %s\n", config, strerror(errno));
134  return -1;
135  }
136  while(!feof(f)) {
137  if (!fgets(buf, sizeof(buf), f)) {
138  continue;
139  }
140  if (!feof(f)) {
141  lineno++;
142  val = strchr(buf, '#');
143  if (val) *val = '\0';
144  while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
145  buf[strlen(buf) - 1] = '\0';
146  if (!strlen(buf))
147  continue;
148  val = buf;
149  while(*val) {
150  if (*val < 33)
151  break;
152  val++;
153  }
154  if (*val) {
155  *val = '\0';
156  val++;
157  while(*val && (*val < 33)) val++;
158  }
159  if (!strcasecmp(buf, "host")) {
160  if (val && strlen(val))
161  strncpy(host, val, sizeof(host) - 1);
162  else
163  fprintf(stderr, "host needs an argument (the host) at line %d\n", lineno);
164  } else if (!strcasecmp(buf, "user")) {
165  if (val && strlen(val))
166  snprintf(user, sizeof(user), "%s", val);
167  else
168  fprintf(stderr, "user needs an argument (the user) at line %d\n", lineno);
169  } else if (!strcasecmp(buf, "pass")) {
170  if (val && strlen(val))
171  snprintf(pass, sizeof(pass), "%s", val);
172  else
173  fprintf(stderr, "pass needs an argument (the password) at line %d\n", lineno);
174  } else if (!strcasecmp(buf, "smoothfade")) {
175  smoothfade = 1;
176  } else if (!strcasecmp(buf, "mutelevel")) {
177  if (val && (sscanf(val, "%3d", &x) == 1) && (x > -1) && (x < 101)) {
178  mutelevel = x;
179  } else
180  fprintf(stderr, "mutelevel must be a number from 0 (most muted) to 100 (no mute) at line %d\n", lineno);
181  } else if (!strcasecmp(buf, "channel")) {
182  if (val && strlen(val)) {
183  val2 = strchr(val, '/');
184  if (val2) {
185  *val2 = '\0';
186  val2++;
187  add_channel(val, val2);
188  } else
189  fprintf(stderr, "channel needs to be of the format Tech/Location at line %d\n", lineno);
190  } else
191  fprintf(stderr, "channel needs an argument (the channel) at line %d\n", lineno);
192  } else {
193  fprintf(stderr, "ignoring unknown keyword '%s'\n", buf);
194  }
195  }
196  }
197  fclose(f);
198  if (!strlen(host))
199  fprintf(stderr, "no 'host' specification in config file\n");
200  else if (!strlen(user))
201  fprintf(stderr, "no 'user' specification in config file\n");
202  else if (!channels)
203  fprintf(stderr, "no 'channel' specifications in config file\n");
204  else
205  return 0;
206  return -1;
207 }
208 
209 static FILE *astf;
210 #ifndef __Darwin__
211 static int mixfd;
212 
213 static int open_mixer(void)
214 {
215  mixfd = open("/dev/mixer", O_RDWR);
216  if (mixfd < 0) {
217  fprintf(stderr, "Unable to open /dev/mixer: %s\n", strerror(errno));
218  return -1;
219  }
220  return 0;
221 }
222 #endif /* !__Darwin */
223 
224 /*! Connect to the asterisk manager interface */
225 static int connect_asterisk(void)
226 {
227  int sock;
228  struct hostent *hp;
229  char *ports;
230  int port = 5038;
231  struct sockaddr_in sin;
232 
233  ports = strchr(host, ':');
234  if (ports) {
235  *ports = '\0';
236  ports++;
237  if ((sscanf(ports, "%5d", &port) != 1) || (port < 1) || (port > 65535)) {
238  fprintf(stderr, "'%s' is not a valid port number in the hostname\n", ports);
239  return -1;
240  }
241  }
242  hp = gethostbyname(host);
243  if (!hp) {
244  fprintf(stderr, "Can't find host '%s'\n", host);
245  return -1;
246  }
247  sock = socket(AF_INET, SOCK_STREAM, 0);
248  if (sock < 0) {
249  fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
250  return -1;
251  }
252  sin.sin_family = AF_INET;
253  sin.sin_port = htons(port);
254  memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
255  if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
256  fprintf(stderr, "Failed to connect to '%s' port '%d': %s\n", host, port, strerror(errno));
257  close(sock);
258  return -1;
259  }
260  astf = fdopen(sock, "r+");
261  if (!astf) {
262  fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
263  close(sock);
264  return -1;
265  }
266  return 0;
267 }
268 
269 static char *get_line(void)
270 {
271  static char buf[1024];
272  if (fgets(buf, sizeof(buf), astf)) {
273  while(strlen(buf) && (buf[strlen(buf) - 1] < 33))
274  buf[strlen(buf) - 1] = '\0';
275  return buf;
276  } else
277  return NULL;
278 }
279 
280 /*! Login to the asterisk manager interface */
281 static int login_asterisk(void)
282 {
283  char *welcome;
284  char *resp;
285  if (!(welcome = get_line())) {
286  fprintf(stderr, "disconnected (1)\n");
287  return -1;
288  }
289  fprintf(astf,
290  "Action: Login\r\n"
291  "Username: %s\r\n"
292  "Secret: %s\r\n\r\n", user, pass);
293  if (!(welcome = get_line())) {
294  fprintf(stderr, "disconnected (2)\n");
295  return -1;
296  }
297  if (strcasecmp(welcome, "Response: Success")) {
298  fprintf(stderr, "login failed ('%s')\n", welcome);
299  return -1;
300  }
301  /* Eat the rest of the event */
302  while((resp = get_line()) && strlen(resp));
303  if (!resp) {
304  fprintf(stderr, "disconnected (3)\n");
305  return -1;
306  }
307  fprintf(astf,
308  "Action: Status\r\n\r\n");
309  if (!(welcome = get_line())) {
310  fprintf(stderr, "disconnected (4)\n");
311  return -1;
312  }
313  if (strcasecmp(welcome, "Response: Success")) {
314  fprintf(stderr, "status failed ('%s')\n", welcome);
315  return -1;
316  }
317  /* Eat the rest of the event */
318  while((resp = get_line()) && strlen(resp));
319  if (!resp) {
320  fprintf(stderr, "disconnected (5)\n");
321  return -1;
322  }
323  return 0;
324 }
325 
326 static struct channel *find_channel(char *channel)
327 {
328  char tmp[256] = "";
329  char *s, *t;
330  struct channel *chan;
331  strncpy(tmp, channel, sizeof(tmp) - 1);
332  s = strchr(tmp, '/');
333  if (s) {
334  *s = '\0';
335  s++;
336  t = strrchr(s, '-');
337  if (t) {
338  *t = '\0';
339  }
340  if (debug)
341  printf("Searching for '%s' tech, '%s' location\n", tmp, s);
342  chan = channels;
343  while(chan) {
344  if (!strcasecmp(chan->tech, tmp) && !strcasecmp(chan->location, s)) {
345  if (debug)
346  printf("Found '%s'/'%s'\n", chan->tech, chan->location);
347  break;
348  }
349  chan = chan->next;
350  }
351  } else
352  chan = NULL;
353  return chan;
354 }
355 
356 #ifndef __Darwin__
357 static int getvol(void)
358 {
359  int vol;
360 
361  if (ioctl(mixfd, MIXER_READ(mixchan), &vol)) {
362 #else
363 static float getvol(void)
364 {
365  float volumeL, volumeR, vol;
366  OSStatus err;
367  AudioDeviceID device;
368  UInt32 size;
369  UInt32 channels[2];
370  AudioObjectPropertyAddress OutputAddr = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
371  AudioObjectPropertyAddress ChannelAddr = { kAudioDevicePropertyPreferredChannelsForStereo, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementWildcard };
372  AudioObjectPropertyAddress VolumeAddr = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, };
373 
374  size = sizeof(device);
375  err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &OutputAddr, 0, NULL, &size, &device);
376  size = sizeof(channels);
377  if (!err) {
378  err = AudioObjectGetPropertyData(device, &ChannelAddr, 0, NULL, &size, &channels);
379  }
380  size = sizeof(vol);
381  if (!err) {
382  VolumeAddr.mElement = channels[0];
383  err = AudioObjectGetPropertyData(device, &VolumeAddr, 0, NULL, &size, &volumeL);
384  }
385  if (!err) {
386  VolumeAddr.mElement = channels[1];
387  err = AudioObjectGetPropertyData(device, &VolumeAddr, 0, NULL, &size, &volumeR);
388  }
389  if (!err)
390  vol = (volumeL < volumeR) ? volumeR : volumeL;
391  else {
392 #endif
393  fprintf(stderr, "Unable to read mixer volume: %s\n", strerror(errno));
394  return -1;
395  }
396  return vol;
397 }
398 
399 #ifndef __Darwin__
400 static int setvol(int vol)
401 #else
402 static int setvol(float vol)
403 #endif
404 {
405 #ifndef __Darwin__
406  if (ioctl(mixfd, MIXER_WRITE(mixchan), &vol)) {
407 #else
408  float volumeL = vol;
409  float volumeR = vol;
410  OSStatus err;
411  AudioDeviceID device;
412  UInt32 size;
413  UInt32 channels[2];
414  AudioObjectPropertyAddress OutputAddr = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
415  AudioObjectPropertyAddress ChannelAddr = { kAudioDevicePropertyPreferredChannelsForStereo, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementWildcard };
416  AudioObjectPropertyAddress VolumeAddr = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, };
417 
418  size = sizeof(device);
419  err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &OutputAddr, 0, NULL, &size, &device);
420  size = sizeof(channels);
421  err = AudioObjectGetPropertyData(device, &ChannelAddr, 0, NULL, &size, &channels);
422  size = sizeof(vol);
423  if (!err) {
424  VolumeAddr.mElement = channels[0];
425  err = AudioObjectSetPropertyData(device, &VolumeAddr, 0, NULL, size, &volumeL);
426  }
427  if (!err) {
428  VolumeAddr.mElement = channels[1];
429  err = AudioObjectSetPropertyData(device, &VolumeAddr, 0, NULL, size, &volumeR);
430  }
431  if (err) {
432 #endif
433 
434  fprintf(stderr, "Unable to write mixer volume: %s\n", strerror(errno));
435  return -1;
436 
437  }
438  return 0;
439 }
440 
441 #ifndef __Darwin__
442 static int oldvol = 0;
443 static int mutevol = 0;
444 #else
445 static float oldvol = 0;
446 static float mutevol = 0;
447 #endif
448 
449 #ifndef __Darwin__
450 static int mutedlevel(int orig, int level)
451 {
452  int l = orig >> 8;
453  int r = orig & 0xff;
454  l = (float)(level) * (float)(l) / 100.0;
455  r = (float)(level) * (float)(r) / 100.0;
456 
457  return (l << 8) | r;
458 #else
459 static float mutedlevel(float orig, float level)
460 {
461  float master = orig;
462  master = level * master / 100.0;
463  return master;
464 #endif
465 
466 }
467 
468 static void mute(void)
469 {
470 #ifndef __Darwin__
471  int vol;
472  int start;
473  int x;
474 #else
475  float vol;
476  float start = 1.0;
477  float x;
478 #endif
479  vol = getvol();
480  oldvol = vol;
481  if (smoothfade)
482 #ifdef __Darwin__
483  start = mutelevel;
484 #else
485  start = 100;
486  else
487  start = mutelevel;
488 #endif
489  for (x=start;x>=mutelevel;x-=stepsize) {
490  mutevol = mutedlevel(vol, x);
491  setvol(mutevol);
492  /* Wait 0.01 sec */
493  usleep(10000);
494  }
495  mutevol = mutedlevel(vol, mutelevel);
496  setvol(mutevol);
497  if (debug)
498 #ifdef __Darwin__
499  printf("Mute from '%f' to '%f'!\n", oldvol, mutevol);
500 #else
501  printf("Mute from '%04x' to '%04x'!\n", oldvol, mutevol);
502 #endif
503  muted = 1;
504 }
505 
506 static void unmute(void)
507 {
508 #ifdef __Darwin__
509  float vol;
510  float start;
511  float x;
512 #else
513  int vol;
514  int start;
515  int x;
516 #endif
517  vol = getvol();
518  if (debug)
519 #ifdef __Darwin__
520  printf("Unmute from '%f' (should be '%f') to '%f'!\n", vol, mutevol, oldvol);
521  mutevol = vol;
522  if (vol == mutevol) {
523 #else
524  printf("Unmute from '%04x' (should be '%04x') to '%04x'!\n", vol, mutevol, oldvol);
525  if ((int)vol == mutevol) {
526 #endif
527  if (smoothfade)
528  start = mutelevel;
529  else
530 #ifdef __Darwin__
531  start = 1.0;
532 #else
533  start = 100;
534 #endif
535  for (x=start;x<100;x+=stepsize) {
536  mutevol = mutedlevel(oldvol, x);
537  setvol(mutevol);
538  /* Wait 0.01 sec */
539  usleep(10000);
540  }
541  setvol(oldvol);
542  } else
543  printf("Whoops, it's already been changed!\n");
544  muted = 0;
545 }
546 
547 static void check_mute(void)
548 {
549  int offhook = 0;
550  struct channel *chan;
551  chan = channels;
552  while(chan) {
553  if (chan->subs) {
554  offhook++;
555  break;
556  }
557  chan = chan->next;
558  }
559  if (offhook && !muted)
560  mute();
561  else if (!offhook && muted)
562  unmute();
563 }
564 
565 static void delete_sub(struct channel *chan, char *name)
566 {
567  struct subchannel *sub, *prev;
568  prev = NULL;
569  sub = chan->subs;
570  while(sub) {
571  if (!strcasecmp(sub->name, name)) {
572  if (prev)
573  prev->next = sub->next;
574  else
575  chan->subs = sub->next;
576  free(sub->name);
577  free(sub);
578  return;
579  }
580  prev = sub;
581  sub = sub->next;
582  }
583 }
584 
585 static void append_sub(struct channel *chan, char *name)
586 {
587  struct subchannel *sub;
588  sub = chan->subs;
589  while(sub) {
590  if (!strcasecmp(sub->name, name))
591  return;
592  sub = sub->next;
593  }
594  sub = malloc(sizeof(struct subchannel));
595  if (sub) {
596  memset(sub, 0, sizeof(struct subchannel));
597  if (!(sub->name = strdup(name))) {
598  free(sub);
599  return;
600  }
601  sub->next = chan->subs;
602  chan->subs = sub;
603  }
604 }
605 
606 static void hangup_chan(char *channel)
607 {
608  struct channel *chan;
609  if (debug)
610  printf("Hangup '%s'\n", channel);
611  chan = find_channel(channel);
612  if (chan)
613  delete_sub(chan, channel);
614  check_mute();
615 }
616 
617 static void offhook_chan(char *channel)
618 {
619  struct channel *chan;
620  if (debug)
621  printf("Offhook '%s'\n", channel);
622  chan = find_channel(channel);
623  if (chan)
624  append_sub(chan, channel);
625  check_mute();
626 }
627 
628 static int wait_event(void)
629 {
630  char *resp;
631  char event[120]="";
632  char channel[120]="";
633  char oldname[120]="";
634  char newname[120]="";
635 
636  resp = get_line();
637  if (!resp) {
638  fprintf(stderr, "disconnected (6)\n");
639  return -1;
640  }
641  if (!strncasecmp(resp, "Event: ", strlen("Event: "))) {
642  int event_len = -1;
643  int channel_len = -1;
644  int newname_len = -1;
645  int oldname_len = -1;
646 
647  event_len = snprintf(event, sizeof(event), "%s", resp + strlen("Event: "));
648  /* Consume the rest of the non-event */
649  while((resp = get_line()) && strlen(resp)) {
650  if (!strncasecmp(resp, "Channel: ", strlen("Channel: ")))
651  channel_len = snprintf(channel, sizeof(channel), "%s", resp + strlen("Channel: "));
652  if (!strncasecmp(resp, "Newname: ", strlen("Newname: ")))
653  newname_len = snprintf(newname, sizeof(newname), "%s", resp + strlen("Newname: "));
654  if (!strncasecmp(resp, "Oldname: ", strlen("Oldname: ")))
655  oldname_len = snprintf(oldname, sizeof(oldname), "%s", resp + strlen("Oldname: "));
656  }
657  if (channel_len == strlen(channel)) {
658  if (event_len == strlen(event) && !strcasecmp(event, "Hangup"))
659  hangup_chan(channel);
660  else
661  offhook_chan(channel);
662  }
663  if (newname_len == strlen(newname) && oldname_len == strlen(oldname)) {
664  if (event_len == strlen(event) && !strcasecmp(event, "Rename")) {
665  hangup_chan(oldname);
666  offhook_chan(newname);
667  }
668  }
669  } else {
670  /* Consume the rest of the non-event */
671  while((resp = get_line()) && strlen(resp));
672  }
673  if (!resp) {
674  fprintf(stderr, "disconnected (7)\n");
675  return -1;
676  }
677  return 0;
678 }
679 
680 static void usage(void)
681 {
682  printf("Usage: muted [-f] [-d]\n"
683  " -f : Do not fork\n"
684  " -d : Debug (implies -f)\n");
685 }
686 
687 int main(int argc, char *argv[])
688 {
689  int x;
690  while((x = getopt(argc, argv, "fhd")) > 0) {
691  switch(x) {
692  case 'd':
693  debug = 1;
694  needfork = 0;
695  break;
696  case 'f':
697  needfork = 0;
698  break;
699  case 'h':
700  /* Fall through */
701  default:
702  usage();
703  exit(1);
704  }
705  }
706  if (load_config())
707  exit(1);
708 #ifndef __Darwin__
709  if (open_mixer())
710  exit(1);
711 #endif
712  if (connect_asterisk()) {
713 #ifndef __Darwin__
714  close(mixfd);
715 #endif
716  exit(1);
717  }
718  if (login_asterisk()) {
719 #ifndef __Darwin__
720  close(mixfd);
721 #endif
722  fclose(astf);
723  exit(1);
724  }
725 #ifdef HAVE_WORKING_FORK
726  if (needfork) {
727 #ifndef HAVE_SBIN_LAUNCHD
728  if (daemon(0,0) < 0) {
729  fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
730  exit(1);
731  }
732 #else
733  const char *found = NULL, *paths[] = {
734  "/Library/LaunchAgents/org.asterisk.muted.plist",
735  "/Library/LaunchDaemons/org.asterisk.muted.plist",
736  "contrib/init.d/org.asterisk.muted.plist",
737  "<path-to-asterisk-source>/contrib/init.d/org.asterisk.muted.plist" };
738  char userpath[256];
739  struct stat unused;
740  struct passwd *pwd = getpwuid(getuid());
741  int i;
742 
743  snprintf(userpath, sizeof(userpath), "%s%s", pwd->pw_dir, paths[0]);
744  if (!stat(userpath, &unused)) {
745  found = userpath;
746  }
747 
748  if (!found) {
749  for (i = 0; i < 3; i++) {
750  if (!stat(paths[i], &unused)) {
751  found = paths[i];
752  break;
753  }
754  }
755  }
756 
757  fprintf(stderr, "Mac OS X detected. Use 'launchctl load -w %s' to launch.\n", found ? found : paths[3]);
758  exit(1);
759 #endif /* !defined(HAVE_SBIN_LAUNCHD */
760  }
761 #endif
762  for(;;) {
763  if (wait_event()) {
764  fclose(astf);
765  while(connect_asterisk()) {
766  sleep(5);
767  }
768  if (login_asterisk()) {
769  fclose(astf);
770  exit(1);
771  }
772  }
773  }
774  exit(0);
775 }
static void check_mute(void)
Definition: muted.c:547
static int mutevol
Definition: muted.c:443
#define gethostbyname
Definition: lock.h:637
Definition: ast_expr2.c:325
static FILE * astf
Definition: muted.c:209
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int wait_event(void)
Definition: muted.c:628
static int muted
Definition: muted.c:82
static int mutedlevel(int orig, int level)
Definition: muted.c:450
static int tmp()
Definition: bt_open.c:389
static void delete_sub(struct channel *chan, char *name)
Definition: muted.c:565
static int smoothfade
Definition: muted.c:80
static void offhook_chan(char *channel)
Definition: muted.c:617
Definition: astman.c:222
char * tech
Definition: muted.c:96
Definition: muted.c:95
#define NULL
Definition: resample.c:96
static int mutelevel
Definition: muted.c:81
static void mute(void)
Definition: muted.c:468
static int mixchan
Definition: muted.c:87
static int connect_asterisk(void)
Definition: muted.c:225
char * malloc()
void free()
static char host[256]
Definition: muted.c:77
static void append_sub(struct channel *chan, char *name)
Definition: muted.c:585
static int login_asterisk(void)
Definition: muted.c:281
static int stepsize
Definition: muted.c:85
static struct channel * channels
static int open_mixer(void)
Definition: muted.c:213
static void unmute(void)
Definition: muted.c:506
static void hangup_chan(char *channel)
Definition: muted.c:606
static int load_config(void)
Definition: muted.c:123
static char * config
Definition: muted.c:75
int errno
static char * get_line(void)
Definition: muted.c:269
static int getvol(void)
Definition: muted.c:357
static int mixfd
Definition: muted.c:211
struct subchannel * subs
Definition: muted.c:99
structure to hold users read from users.conf
static struct channel * find_channel(char *channel)
Definition: muted.c:326
static void usage(void)
Definition: muted.c:680
static int setvol(int vol)
Definition: muted.c:400
struct stasis_forward * sub
Definition: res_corosync.c:240
char * name
Definition: muted.c:91
static int oldvol
Definition: muted.c:442
#define strdup(a)
Definition: astmm.h:165
struct subchannel * next
Definition: muted.c:92
static void add_channel(char *tech, char *location)
Definition: muted.c:102
struct channel * next
Definition: muted.c:98
static struct hostent * hp
Definition: chan_skinny.c:1236
static int needfork
Definition: muted.c:83
int main(int argc, char *argv[])
Definition: muted.c:687
char * location
Definition: muted.c:97
static char pass[256]
Definition: muted.c:79
static int debug
Definition: muted.c:84