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

Annotation of src/usr.bin/midicat/midicat.c, Revision 1.6

1.6     ! cheloha     1: /*     $OpenBSD: midicat.c,v 1.5 2022/12/02 22:21:35 cheloha Exp $     */
1.1       ratchov     2: /*
                      3:  * Copyright (c) 2015 Alexandre Ratchov <alex@caoua.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: #include <err.h>
                     18: #include <fcntl.h>
                     19: #include <sndio.h>
                     20: #include <stdio.h>
                     21: #include <stdlib.h>
                     22: #include <unistd.h>
                     23: #include <string.h>
                     24:
1.5       cheloha    25: void __dead usage(void);
1.1       ratchov    26:
                     27: int
                     28: main(int argc, char **argv)
                     29: {
                     30: #define MIDI_BUFSZ     1024
                     31:        unsigned char buf[MIDI_BUFSZ];
                     32:        struct mio_hdl *ih, *oh;
                     33:        char *port0, *port1, *ifile, *ofile;
                     34:        int ifd, ofd;
                     35:        int dump, c, i, len, n, sep, mode;
                     36:
                     37:        dump = 0;
                     38:        port0 = port1 = ifile = ofile = NULL;
                     39:        ih = oh = NULL;
                     40:        ifd = ofd = -1;
                     41:
                     42:        while ((c = getopt(argc, argv, "di:o:q:")) != -1) {
                     43:                switch (c) {
                     44:                case 'd':
                     45:                        dump = 1;
                     46:                        break;
                     47:                case 'q':
                     48:                        if (port0 == NULL)
                     49:                                port0 = optarg;
                     50:                        else if (port1 == NULL)
                     51:                                port1 = optarg;
                     52:                        else {
                     53:                                fputs("too many -q options\n", stderr);
                     54:                                return 1;
                     55:                        }
                     56:                        break;
                     57:                case 'i':
                     58:                        ifile = optarg;
                     59:                        break;
                     60:                case 'o':
                     61:                        ofile = optarg;
                     62:                        break;
                     63:                default:
1.5       cheloha    64:                        usage();
1.1       ratchov    65:                }
                     66:        }
                     67:        argc -= optind;
                     68:        argv += optind;
1.5       cheloha    69:
                     70:        if (argc != 0)
                     71:                usage();
1.1       ratchov    72:
                     73:        /* we don't support more than one data flow */
                     74:        if (ifile != NULL && ofile != NULL) {
                     75:                fputs("-i and -o are exclusive\n", stderr);
                     76:                return 1;
                     77:        }
                     78:
                     79:        /* second port makes sense only for port-to-port transfers */
                     80:        if (port1 != NULL && !(ifile == NULL && ofile == NULL)) {
                     81:                fputs("too many -q options\n", stderr);
                     82:                return 1;
                     83:        }
                     84:
                     85:        /* if there're neither files nor ports, then we've nothing to do */
                     86:        if (port0 == NULL && ifile == NULL && ofile == NULL)
1.5       cheloha    87:                usage();
1.1       ratchov    88:
                     89:        /* if no port specified, use default one */
                     90:        if (port0 == NULL)
                     91:                port0 = MIO_PORTANY;
                     92:
                     93:        /* open input or output file (if any) */
                     94:        if (ifile) {
1.6     ! cheloha    95:                if (strcmp(ifile, "-") == 0) {
        !            96:                        ifile = "stdin";
1.1       ratchov    97:                        ifd = STDIN_FILENO;
1.6     ! cheloha    98:                } else {
1.3       deraadt    99:                        ifd = open(ifile, O_RDONLY);
1.2       deraadt   100:                        if (ifd == -1) {
1.1       ratchov   101:                                perror(ifile);
                    102:                                return 1;
                    103:                        }
                    104:                }
                    105:        } else if (ofile) {
1.6     ! cheloha   106:                if (strcmp(ofile, "-") == 0) {
        !           107:                        ofile = "stdout";
1.1       ratchov   108:                        ofd = STDOUT_FILENO;
1.6     ! cheloha   109:                } else {
1.1       ratchov   110:                        ofd = open(ofile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1.2       deraadt   111:                        if (ofd == -1) {
1.1       ratchov   112:                                perror(ofile);
                    113:                                return 1;
                    114:                        }
                    115:                }
                    116:        }
                    117:
                    118:        /* open first port for input and output (if output needed) */
                    119:        if (ofile)
                    120:                mode = MIO_IN;
                    121:        else if (ifile)
                    122:                mode = MIO_OUT;
                    123:        else if (port1 == NULL)
                    124:                mode = MIO_IN | MIO_OUT;
                    125:        else
                    126:                mode = MIO_IN;
                    127:        ih = mio_open(port0, mode, 0);
                    128:        if (ih == NULL) {
                    129:                fprintf(stderr, "%s: couldn't open port\n", port0);
                    130:                return 1;
                    131:        }
                    132:
                    133:        /* open second port, output only */
                    134:        if (port1 == NULL)
                    135:                oh = ih;
                    136:        else {
                    137:                oh = mio_open(port1, MIO_OUT, 0);
                    138:                if (oh == NULL) {
                    139:                        fprintf(stderr, "%s: couldn't open port\n", port1);
                    140:                        exit(1);
                    141:                }
                    142:        }
                    143:
1.2       deraadt   144:        if (pledge("stdio", NULL) == -1)
1.1       ratchov   145:                err(1, "pledge");
                    146:
                    147:        /* transfer until end-of-file or error */
                    148:        for (;;) {
                    149:                if (ifile != NULL) {
                    150:                        len = read(ifd, buf, sizeof(buf));
                    151:                        if (len == 0)
                    152:                                break;
1.2       deraadt   153:                        if (len == -1) {
1.1       ratchov   154:                                perror("stdin");
                    155:                                break;
                    156:                        }
                    157:                } else {
                    158:                        len = mio_read(ih, buf, sizeof(buf));
                    159:                        if (len == 0) {
                    160:                                fprintf(stderr, "%s: disconnected\n", port0);
                    161:                                break;
                    162:                        }
                    163:                }
                    164:                if (ofile != NULL) {
                    165:                        n = write(ofd, buf, len);
                    166:                        if (n != len) {
                    167:                                fprintf(stderr, "%s: short write\n", ofile);
                    168:                                break;
                    169:                        }
                    170:                } else {
                    171:                        n = mio_write(oh, buf, len);
                    172:                        if (n != len) {
                    173:                                fprintf(stderr, "%s: disconnected\n", port1);
                    174:                                break;
                    175:                        }
                    176:                }
                    177:                if (dump) {
                    178:                        for (i = 0; i < len; i++) {
                    179:                                sep = (i % 16 == 15 || i == len - 1) ?
                    180:                                    '\n' : ' ';
                    181:                                fprintf(stderr, "%02x%c", buf[i], sep);
                    182:                        }
                    183:                }
                    184:        }
                    185:
                    186:        /* clean-up */
                    187:        if (port0)
                    188:                mio_close(ih);
                    189:        if (port1)
                    190:                mio_close(oh);
                    191:        if (ifile)
                    192:                close(ifd);
                    193:        if (ofile)
                    194:                close(ofd);
                    195:        return 0;
1.5       cheloha   196: }
                    197:
                    198: void __dead
                    199: usage(void)
                    200: {
                    201:        fprintf(stderr, "usage: midicat [-d] [-i in-file] [-o out-file] "
                    202:            "[-q in-port] [-q out-port]\n");
                    203:        exit(1);
1.1       ratchov   204: }