/* * p3sysexcat - cat P3 SYSEX data with a pause between blocks * AYM 2005-08-13 */ /* This file is copyright André Majorel 2005. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include static void err (const char *fmt, ...); static int do_file (const char *pathname, FILE *fp); static int wait_ms = 150; int main (int argc, char *argv[]) { int status = 0; if (argc == 2 && strcmp (argv[1], "--help") == 0) { printf ( "Usage:\n" " p3sysexcat --help\n" " p3sysexcat [-w num] [file ...]\n" "Options:\n" " --help Print usage to standard output and exit successfully\n" " -w num Wait num ms between blocks (default %d)\n", wait_ms ); exit (0); } { int g; while ((g = getopt (argc, argv, "w:")) != EOF) { if (g == 'w') { wait_ms = atoi (optarg); if (wait_ms < 0 || wait_ms > 999) { err ("-w: invalid argument \"%s\" (not 0..999)", optarg); exit (1); } } else exit (1); } } if (isatty (fileno (stdout))) { err ("not writing SYSEX data to a terminal"); exit (1); } if (optind >= argc) { if (do_file ("(stdin)", stdin) != 0) status = 1; } else { int n; for (n = optind; n < argc; n++) { FILE *fp = fopen (argv[n], "rb"); if (fp == NULL) { err ("%s: %s", argv[n], strerror (errno)); status = 1; break; } if (do_file (argv[n], fp) != 0) status = 1; fclose (fp); } } return status; } /* * do_file - cat one file * * Returns 0 on success, non-zero on failure. */ static int do_file (const char *pathname, FILE *fp) { int c; unsigned long o; unsigned long blocknum; blocknum = 0; for (o = 0; (c = getc (fp)) != EOF; o++) { if (c == 0xf0) { err ("%s block %lu", pathname, blocknum); blocknum++; } if (putchar (c) == EOF) { err ("(stdout): write error"); return 1; } if (c == 0xf7) { if (blocknum > 0) { struct timespec ts; if (fflush (stdout) != 0) { err ("(stdout): %s", strerror (errno)); return 1; } ts.tv_sec = 0; ts.tv_nsec = wait_ms * 1000 * 1000L; if (nanosleep (&ts, NULL) != 0) { err ("nanosleep: %s", strerror (errno)); return 1; } } } } if (ferror (fp)) { err ("%s: read error", pathname); return 1; } return 0; } /* * err - print an error message */ static void err (const char *fmt, ...) { va_list argp; fputs ("p3sysexcat: ", stderr); va_start (argp, fmt); vfprintf (stderr, fmt, argp); va_end (argp); fputc ('\n', stderr); }