[BACK]Return to aucat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Diff for /src/usr.bin/aucat/aucat.c between version 1.141 and 1.142

version 1.141, 2012/12/03 15:35:25 version 1.142, 2013/11/12 06:47:34
Line 39 
Line 39 
 #include "aproc.h"  #include "aproc.h"
 #include "conf.h"  #include "conf.h"
 #include "dev.h"  #include "dev.h"
 #include "listen.h"  
 #include "midi.h"  #include "midi.h"
 #include "opt.h"  
 #include "wav.h"  #include "wav.h"
 #ifdef DEBUG  #ifdef DEBUG
 #include "dbg.h"  #include "dbg.h"
 #endif  #endif
   
 /*  
  * unprivileged user name  
  */  
 #ifndef SNDIO_USER  
 #define SNDIO_USER      "_sndio"  
 #endif  
   
 /*  
  * priority when run as root  
  */  
 #ifndef SNDIO_PRIO  
 #define SNDIO_PRIO      (-20)  
 #endif  
   
 #define PROG_AUCAT      "aucat"  #define PROG_AUCAT      "aucat"
 #define PROG_SNDIOD     "sndiod"  
   
 /*  /*
  * sample rate if no ``-r'' is used   * sample rate if no ``-r'' is used
Line 85 
Line 68 
 #define DEFAULT_BUFSZ   7860  #define DEFAULT_BUFSZ   7860
 #endif  #endif
   
 /*  
  * default device in server mode  
  */  
 #ifndef DEFAULT_DEV  
 #define DEFAULT_DEV "rsnd/0"  
 #endif  
   
 #ifdef DEBUG  #ifdef DEBUG
 volatile sig_atomic_t debug_level = 1;  volatile sig_atomic_t debug_level = 1;
 #endif  #endif
 volatile sig_atomic_t quit_flag = 0;  volatile sig_atomic_t quit_flag = 0;
   
 char aucat_usage[] = "usage: " PROG_AUCAT " [-dMn] "  char aucat_usage[] = "usage: " PROG_AUCAT " [-dMn]\n\t"
     "[-C min:max] [-c min:max] [-e enc] [-f device]\n\t"      "[-C min:max] [-c min:max] [-e enc] [-f device]\n\t"
     "[-h fmt] [-i file] [-j flag] [-m mode] [-o file] [-q port]\n\t"      "[-h fmt] [-i file] [-j flag] [-o file] [-q port]\n\t"
     "[-r rate] [-t mode] [-v volume] [-w flag] [-x policy]\n";      "[-r rate] [-t mode] [-v volume] [-w flag] [-x policy]\n";
   
 char sndiod_usage[] = "usage: " PROG_SNDIOD " [-dM] [-a flag] [-b nframes] "  
     "[-C min:max] [-c min:max] [-e enc]\n\t"  
     "[-f device] [-j flag] [-L addr] [-m mode] [-q port] [-r rate]\n\t"  
     "[-s name] [-t mode] [-U unit] [-v volume] [-w flag] [-x policy]\n\t"  
     "[-z nframes]\n";  
   
 /*  /*
  * SIGINT handler, it raises the quit flag. If the flag is already set,   * SIGINT handler, it raises the quit flag. If the flag is already set,
  * that means that the last SIGINT was not handled, because the process   * that means that the last SIGINT was not handled, because the process
Line 219 
Line 189 
         errx(1, "%s: bad underrun/overrun policy", optarg);          errx(1, "%s: bad underrun/overrun policy", optarg);
 }  }
   
 unsigned int  
 opt_mode(void)  
 {  
         unsigned int mode = 0;  
         char *p = optarg;  
         size_t len;  
   
         for (p = optarg; *p != '\0'; p++) {  
                 len = strcspn(p, ",");  
                 if (strncmp("play", p, len) == 0) {  
                         mode |= MODE_PLAY;  
                 } else if (strncmp("rec", p, len) == 0) {  
                         mode |= MODE_REC;  
                 } else if (strncmp("mon", p, len) == 0) {  
                         mode |= MODE_MON;  
                 } else if (strncmp("midi", p, len) == 0) {  
                         mode |= MODE_MIDIMASK;  
                 } else  
                         errx(1, "%s: bad mode", optarg);  
                 p += len;  
                 if (*p == '\0')  
                         break;  
         }  
         if (mode == 0)  
                 errx(1, "empty mode");  
         return mode;  
 }  
   
 void  void
 setsig(void)  setsig(void)
 {  {
Line 294 
Line 236 
                 err(1, "unsetsig(int): sigaction failed\n");                  err(1, "unsetsig(int): sigaction failed\n");
 }  }
   
 void  
 getbasepath(char *base, size_t size)  
 {  
         uid_t uid;  
         struct stat sb;  
         mode_t mask;  
   
         uid = geteuid();  
         if (uid == 0) {  
                 mask = 022;  
                 snprintf(base, PATH_MAX, "/tmp/aucat");  
         } else {  
                 mask = 077;  
                 snprintf(base, PATH_MAX, "/tmp/aucat-%u", uid);  
         }  
         if (mkdir(base, 0777 & ~mask) < 0) {  
                 if (errno != EEXIST)  
                         err(1, "mkdir(\"%s\")", base);  
         }  
         if (stat(base, &sb) < 0)  
                 err(1, "stat(\"%s\")", base);  
         if (sb.st_uid != uid || (sb.st_mode & mask) != 0)  
                 errx(1, "%s has wrong permissions", base);  
 }  
   
 void  
 privdrop(void)  
 {  
         struct passwd *pw;  
   
         if ((pw = getpwnam(SNDIO_USER)) == NULL)  
                 errx(1, "unknown user %s", SNDIO_USER);  
         if (setpriority(PRIO_PROCESS, 0, SNDIO_PRIO) < 0)  
                 err(1, "setpriority");  
         if (setgroups(1, &pw->pw_gid) ||  
             setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||  
             setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))  
                 err(1, "cannot drop privileges");  
 }  
   
 struct dev *  struct dev *
 mkdev(char *path, int mode, int bufsz, int round, int hold, int autovol)  mkdev(char *path, int mode, int bufsz, int round, int hold, int autovol)
 {  {
Line 364 
Line 266 
         return d;          return d;
 }  }
   
 struct opt *  
 mkopt(char *path, struct dev *d, struct aparams *rpar, struct aparams *ppar,  
     int mode, int vol, int mmc, int join)  
 {  
         struct opt *o;  
   
         if (d->reqmode & MODE_LOOP)  
                 errx(1, "%s: can't attach to loopback", path);  
         if (d->reqmode & MODE_THRU)  
                 mode = MODE_MIDIMASK;  
         if (!rpar->rate)  
                 ppar->rate = rpar->rate = DEFAULT_RATE;  
         o = opt_new(path, d, rpar, ppar, MIDI_TO_ADATA(vol), mmc, join, mode);  
         if (o == NULL)  
                 errx(1, "%s: couldn't create subdev", path);  
         dev_adjpar(d, o->mode, rpar, ppar);  
         return o;  
 }  
   
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         char *prog, *optstr, *usagestr;  
         int c, background, unit, active;          int c, background, unit, active;
         char base[PATH_MAX], path[PATH_MAX];  
         unsigned int mode, hdr, xrun, rate, join, mmc, vol;          unsigned int mode, hdr, xrun, rate, join, mmc, vol;
         unsigned int hold, autovol, bufsz, round;          unsigned int hold, autovol, bufsz, round;
         const char *str;          const char *str;
         struct aparams ppar, rpar;          struct aparams ppar, rpar;
         struct dev *d, *dnext;          struct dev *d, *dnext;
         struct listen *l;  
         struct wav *w;          struct wav *w;
   
         /*          /*
Line 421 
Line 301 
         setsig();          setsig();
         filelist_init();          filelist_init();
   
         prog = strrchr(argv[0], '/');          while ((c = getopt(argc, argv,
         if (prog == NULL)                      "a:b:c:C:de:f:h:i:j:Mno:q:r:t:v:w:x:z:")) != -1) {
                 prog = argv[0];  
         else  
                 prog++;  
         if (strcmp(prog, PROG_AUCAT) == 0) {  
                 optstr = "a:b:c:C:de:f:h:i:j:L:m:Mno:q:r:s:t:U:v:w:x:z:";  
                 usagestr = aucat_usage;  
                 hold = 1;  
         } else if (strcmp(prog, PROG_SNDIOD) == 0) {  
                 optstr = "a:b:c:C:de:f:j:L:m:Mq:r:s:t:U:v:w:x:z:";  
                 usagestr = sndiod_usage;  
                 background = 1;  
         } else  
                 errx(1, "%s: can't determine program to run", prog);  
   
         while ((c = getopt(argc, argv, optstr)) != -1) {  
                 switch (c) {                  switch (c) {
                 case 'd':                  case 'd':
 #ifdef DEBUG  #ifdef DEBUG
Line 446 
Line 311 
 #endif  #endif
                         background = 0;                          background = 0;
                         break;                          break;
                 case 'U':  
                         if (listen_list)  
                                 errx(1, "-U must come before -L");  
                         unit = strtonum(optarg, 0, MIDI_MAXCTL, &str);  
                         if (str)  
                                 errx(1, "%s: unit number is %s", optarg, str);  
                         break;  
                 case 'L':  
                         listen_new_tcp(optarg, AUCAT_PORT + unit);  
                         break;  
                 case 'm':  
                         mode = opt_mode();  
                         break;  
                 case 'h':                  case 'h':
                         hdr = opt_hdr();                          hdr = opt_hdr();
                         break;                          break;
Line 510 
Line 362 
                                 errx(1, "%s: couldn't create stream", optarg);                                  errx(1, "%s: couldn't create stream", optarg);
                         dev_adjpar(d, w->mode, &w->hpar, NULL);                          dev_adjpar(d, w->mode, &w->hpar, NULL);
                         break;                          break;
                 case 's':  
                         if ((d = dev_list) == NULL) {  
                                 d = mkdev(DEFAULT_DEV, 0, bufsz, round,  
                                     hold, autovol);  
                         }  
                         mkopt(optarg, d, &rpar, &ppar, mode, vol, mmc, join);  
                         /* XXX: set device rate, if never set */  
                         break;  
                 case 'q':                  case 'q':
                         d = mkdev(NULL, mode, bufsz, round, 1, autovol);                          d = mkdev(NULL, mode, bufsz, round, 1, autovol);
                         if (!devctl_add(d, optarg, MODE_MIDIMASK))                          if (!devctl_add(d, optarg, MODE_MIDIMASK))
                                 errx(1, "%s: can't open port", optarg);                                  errx(1, "%s: can't open port", optarg);
                         d->reqmode |= MODE_MIDIMASK;                          d->reqmode |= MODE_MIDIMASK;
                         break;                          break;
                 case 'a':  
                         hold = opt_onoff();  
                         break;  
                 case 'w':                  case 'w':
                         autovol = opt_onoff();                          autovol = opt_onoff();
                         break;                          break;
Line 550 
Line 391 
                         mkdev("midithru", MODE_THRU, 0, 0, hold, 0);                          mkdev("midithru", MODE_THRU, 0, 0, hold, 0);
                         break;                          break;
                 default:                  default:
                         fputs(usagestr, stderr);                          fputs(aucat_usage, stderr);
                         exit(1);                          exit(1);
                 }                  }
         }          }
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
         if (argc > 0) {          if (argc > 0) {
                 fputs(usagestr, stderr);                  fputs(aucat_usage, stderr);
                 exit(1);                  exit(1);
         }          }
         if (wav_list) {          if (wav_list) {
                 if (opt_list || listen_list)  
                         errx(1, "-io not allowed in server mode");  
                 if ((d = dev_list) && d->next)                  if ((d = dev_list) && d->next)
                         errx(1, "only one device allowed in non-server mode");                          errx(1, "only one device allowed");
                 if ((d->reqmode & MODE_THRU) && d->ctl_list == NULL) {                  if ((d->reqmode & MODE_THRU) && d->ctl_list == NULL) {
                         if (!devctl_add(d, "default", MODE_MIDIMASK))                          if (!devctl_add(d, "default", MODE_MIDIMASK))
                                 errx(1, "%s: can't open port", optarg);                                  errx(1, "%s: can't open port", optarg);
                         d->reqmode |= MODE_MIDIMASK;                          d->reqmode |= MODE_MIDIMASK;
                 }                  }
         } else {          } else {
                 if (dev_list == NULL)                  fputs(aucat_usage, stderr);
                         mkdev(DEFAULT_DEV, 0, bufsz, round, hold, autovol);                  exit(1);
                 for (d = dev_list; d != NULL; d = d->next) {  
                         if (opt_byname("default", d->num))  
                                 continue;  
                         mkopt("default", d, &rpar, &ppar, mode, vol, mmc, join);  
                 }  
         }          }
         if (opt_list) {  
                 getbasepath(base, sizeof(base));  
                 snprintf(path, PATH_MAX, "%s/%s%u", base, AUCAT_PATH, unit);  
                 listen_new_un(path);  
                 if (geteuid() == 0)  
                         privdrop();  
         }  
         for (w = wav_list; w != NULL; w = w->next) {          for (w = wav_list; w != NULL; w = w->next) {
                 if (!wav_init(w))                  if (!wav_init(w))
                         exit(1);                          exit(1);
Line 596 
Line 423 
                 if (d->autostart && (d->mode & MODE_AUDIOMASK))                  if (d->autostart && (d->mode & MODE_AUDIOMASK))
                         dev_mmcstart(d);                          dev_mmcstart(d);
         }          }
         for (l = listen_list; l != NULL; l = l->next) {  
                 if (!listen_init(l))  
                         exit(1);  
         }  
         if (background) {  
 #ifdef DEBUG  
                 debug_level = 0;  
                 dbg_flush();  
 #endif  
                 if (daemon(0, 0) < 0)  
                         err(1, "daemon");  
         }  
   
         /*          /*
          * Loop, start audio.           * Loop, start audio.
Line 625 
Line 440 
                 }                  }
                 if (dev_list == NULL)                  if (dev_list == NULL)
                         break;                          break;
                 if (!opt_list && !active)                  if (!active)
                         break;                          break;
                 if (!file_poll())                  if (!file_poll())
                         break;                          break;
         }          }
   fatal:    fatal:
         while (listen_list != NULL)  
                 file_close(&listen_list->file);  
   
         /*          /*
          * give a chance to drain           * give a chance to drain
Line 645 
Line 458 
         while (dev_list)          while (dev_list)
                 dev_del(dev_list);                  dev_del(dev_list);
         filelist_done();          filelist_done();
         if (opt_list) {  
                 if (rmdir(base) < 0 && errno != ENOTEMPTY && errno != EPERM)  
                         warn("rmdir(\"%s\")", base);  
         }  
         unsetsig();          unsetsig();
         return 0;          return 0;
 }  }

Legend:
Removed from v.1.141  
changed lines
  Added in v.1.142