[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.2

1.1       ratchov     1: /*
                      2:  * Copyright (c) 2015 Alexandre Ratchov <alex@caoua.org>
                      3:  *
                      4:  * Permission to use, copy, modify, and distribute this software for any
                      5:  * purpose with or without fee is hereby granted, provided that the above
                      6:  * copyright notice and this permission notice appear in all copies.
                      7:  *
                      8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                      9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     15:  */
                     16: #include <err.h>
                     17: #include <fcntl.h>
                     18: #include <sndio.h>
                     19: #include <stdio.h>
                     20: #include <stdlib.h>
                     21: #include <unistd.h>
                     22: #include <string.h>
                     23:
                     24: char usagestr[] = "usage: midicat [-d] [-i in-file] [-o out-file] "
                     25:        "[-q in-port] [-q out-port]\n";
                     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:
                     64:                        goto bad_usage;
                     65:                }
                     66:        }
                     67:        argc -= optind;
                     68:        argv += optind;
                     69:        if (argc != 0) {
                     70:        bad_usage:
                     71:                fputs(usagestr, stderr);
                     72:                return 1;
                     73:        }
                     74:
                     75:        /* we don't support more than one data flow */
                     76:        if (ifile != NULL && ofile != NULL) {
                     77:                fputs("-i and -o are exclusive\n", stderr);
                     78:                return 1;
                     79:        }
                     80:
                     81:        /* second port makes sense only for port-to-port transfers */
                     82:        if (port1 != NULL && !(ifile == NULL && ofile == NULL)) {
                     83:                fputs("too many -q options\n", stderr);
                     84:                return 1;
                     85:        }
                     86:
                     87:        /* if there're neither files nor ports, then we've nothing to do */
                     88:        if (port0 == NULL && ifile == NULL && ofile == NULL)
                     89:                goto bad_usage;
                     90:
                     91:        /* if no port specified, use default one */
                     92:        if (port0 == NULL)
                     93:                port0 = MIO_PORTANY;
                     94:
                     95:        /* open input or output file (if any) */
                     96:        if (ifile) {
                     97:                if (strcmp(ifile, "-") == 0)
                     98:                        ifd = STDIN_FILENO;
                     99:                else {
                    100:                        ifd = open(ifile, O_RDONLY, 0);
1.2     ! deraadt   101:                        if (ifd == -1) {
1.1       ratchov   102:                                perror(ifile);
                    103:                                return 1;
                    104:                        }
                    105:                }
                    106:        } else if (ofile) {
                    107:                if (strcmp(ofile, "-") == 0)
                    108:                        ofd = STDOUT_FILENO;
                    109:                else {
                    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;
                    196: }