auopen.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <err.h>
  8. #include <sysexits.h>
  9. #define INITIAL_SIZE 64
  10. int
  11. main(int argc, char *argv[])
  12. {
  13. uint8_t b[INITIAL_SIZE];
  14. const char *util = NULL;
  15. ssize_t r;
  16. int fd;
  17. if (argv[1] == NULL)
  18. goto usage;
  19. if ((fd = open(argv[1], O_RDONLY)) < 0)
  20. err(EX_NOINPUT, "%s", argv[1]);
  21. if ((r = read(fd, b, sizeof(b))) < 0)
  22. err(EX_IOERR, "%s", argv[1]);
  23. if (r < 4)
  24. err(EX_DATAERR, "%s", argv[1]);
  25. if (memcmp(b, ".snd", 4) == 0) {
  26. util = "au2au";
  27. } else if (memcmp(b, "FORM", 4) == 0) {
  28. if (r < 12)
  29. return (1);
  30. if (memcmp(b + 8, "AIFF", 4) != 0 &&
  31. memcmp(b + 8, "AIFC", 4) != 0)
  32. util = "aiff2au";
  33. } else if (memcmp(b, "RIFF", 4) == 0) {
  34. if (r < 12)
  35. return (1);
  36. if (memcmp(b + 8, "WAVE", 4) == 0)
  37. util = "wav2au";
  38. } else if (memcmp(b, "fLaC", 4) == 0) {
  39. util = "flac2au";
  40. } else if (memcmp(b, "OggS", 4) == 0) {
  41. if (r < 36)
  42. return (1);
  43. if (memcmp(b + 28, "\x01vorbis", 7) == 0)
  44. util = "vorbis2au";
  45. else if (memcmp(b + 28, "\177FLAC", 5) == 0)
  46. util = "flac2au";
  47. } else if (memcmp(b, "ID3", 3) == 0) {
  48. util = "mpg2au";
  49. } else if (
  50. b[0] == 0xFF && (b[1] & 0xE0) == 0xE0 && /* frame sync */
  51. (b[1] & 0x18) != 0x08 && /* version */
  52. (b[1] & 0x06) != 0x00 && /* layer */
  53. (b[2] & 0xF0) != 0xF0 && /* bit-rate */
  54. (b[2] & 0x0C) != 0x0C && /* frequency */
  55. (b[3] & 0x03) != 0x02 /* emphasis */
  56. ) {
  57. util = "mpg2au";
  58. }
  59. if (util == NULL)
  60. return (1);
  61. if (lseek(fd, 0, SEEK_SET) != 0)
  62. err(EX_USAGE, "%s", argv[1]);
  63. if (dup2(fd, STDIN_FILENO) != STDIN_FILENO)
  64. err(EX_OSERR, "dup2(2)");
  65. argv[1] = (char *)util;
  66. (void)execvp(util, argv + 1);
  67. return (1);
  68. usage:
  69. (void)fprintf(stderr, "usage: auopen file [argument ...]\n");
  70. return (EX_USAGE);
  71. }