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

1.4     ! cheloha     1: /*     $OpenBSD$       */
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:
                     25: char usagestr[] = "usage: midicat [-d] [-i in-file] [-o out-file] "
                     26:        "[-q in-port] [-q out-port]\n";
                     27:
                     28: int
                     29: main(int argc, char **argv)
                     30: {
                     31: #define MIDI_BUFSZ     1024
                     32:        unsigned char buf[MIDI_BUFSZ];
                     33:        struct mio_hdl *ih, *oh;
                     34:        char *port0, *port1, *ifile, *ofile;
                     35:        int ifd, ofd;
                     36:        int dump, c, i, len, n, sep, mode;
                     37:
                     38:        dump = 0;
                     39:        port0 = port1 = ifile = ofile = NULL;
                     40:        ih = oh = NULL;
                     41:        ifd = ofd = -1;
                     42:
                     43:        while ((c = getopt(argc, argv, "di:o:q:")) != -1) {
                     44:                switch (c) {
                     45:                case 'd':
                     46:                        dump = 1;
                     47:                        break;
                     48:                case 'q':
                     49:                        if (port0 == NULL)
                     50:                                port0 = optarg;
                     51:                        else if (port1 == NULL)
                     52:                                port1 = optarg;
                     53:                        else {
                     54:                                fputs("too many -q options\n", stderr);
                     55:                                return 1;
                     56:                        }
                     57:                        break;
                     58:                case 'i':
                     59:                        ifile = optarg;
                     60:                        break;
                     61:                case 'o':
                     62:                        ofile = optarg;
                     63:                        break;
                     64:                default:
                     65:                        goto bad_usage;
                     66:                }
                     67:        }
                     68:        argc -= optind;
                     69:        argv += optind;
                     70:        if (argc != 0) {
                     71:        bad_usage:
                     72:                fputs(usagestr, stderr);
                     73:                return 1;
                     74:        }
                     75:
                     76:        /* we don't support more than one data flow */
                     77:        if (ifile != NULL && ofile != NULL) {
                     78:                fputs("-i and -o are exclusive\n", stderr);
                     79:                return 1;
                     80:        }
                     81:
                     82:        /* second port makes sense only for port-to-port transfers */
                     83:        if (port1 != NULL && !(ifile == NULL && ofile == NULL)) {
                     84:                fputs("too many -q options\n", stderr);
                     85:                return 1;
                     86:        }
                     87:
                     88:        /* if there're neither files nor ports, then we've nothing to do */
                     89:        if (port0 == NULL && ifile == NULL && ofile == NULL)
                     90:                goto bad_usage;
                     91:
                     92:        /* if no port specified, use default one */
                     93:        if (port0 == NULL)
                     94:                port0 = MIO_PORTANY;
                     95:
                     96:        /* open input or output file (if any) */
                     97:        if (ifile) {
                     98:                if (strcmp(ifile, "-") == 0)
                     99:                        ifd = STDIN_FILENO;
                    100:                else {
1.3       deraadt   101:                        ifd = open(ifile, O_RDONLY);
1.2       deraadt   102:                        if (ifd == -1) {
1.1       ratchov   103:                                perror(ifile);
                    104:                                return 1;
                    105:                        }
                    106:                }
                    107:        } else if (ofile) {
                    108:                if (strcmp(ofile, "-") == 0)
                    109:                        ofd = STDOUT_FILENO;
                    110:                else {
                    111:                        ofd = open(ofile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1.2       deraadt   112:                        if (ofd == -1) {
1.1       ratchov   113:                                perror(ofile);
                    114:                                return 1;
                    115:                        }
                    116:                }
                    117:        }
                    118:
                    119:        /* open first port for input and output (if output needed) */
                    120:        if (ofile)
                    121:                mode = MIO_IN;
                    122:        else if (ifile)
                    123:                mode = MIO_OUT;
                    124:        else if (port1 == NULL)
                    125:                mode = MIO_IN | MIO_OUT;
                    126:        else
                    127:                mode = MIO_IN;
                    128:        ih = mio_open(port0, mode, 0);
                    129:        if (ih == NULL) {
                    130:                fprintf(stderr, "%s: couldn't open port\n", port0);
                    131:                return 1;
                    132:        }
                    133:
                    134:        /* open second port, output only */
                    135:        if (port1 == NULL)
                    136:                oh = ih;
                    137:        else {
                    138:                oh = mio_open(port1, MIO_OUT, 0);
                    139:                if (oh == NULL) {
                    140:                        fprintf(stderr, "%s: couldn't open port\n", port1);
                    141:                        exit(1);
                    142:                }
                    143:        }
                    144:
1.2       deraadt   145:        if (pledge("stdio", NULL) == -1)
1.1       ratchov   146:                err(1, "pledge");
                    147:
                    148:        /* transfer until end-of-file or error */
                    149:        for (;;) {
                    150:                if (ifile != NULL) {
                    151:                        len = read(ifd, buf, sizeof(buf));
                    152:                        if (len == 0)
                    153:                                break;
1.2       deraadt   154:                        if (len == -1) {
1.1       ratchov   155:                                perror("stdin");
                    156:                                break;
                    157:                        }
                    158:                } else {
                    159:                        len = mio_read(ih, buf, sizeof(buf));
                    160:                        if (len == 0) {
                    161:                                fprintf(stderr, "%s: disconnected\n", port0);
                    162:                                break;
                    163:                        }
                    164:                }
                    165:                if (ofile != NULL) {
                    166:                        n = write(ofd, buf, len);
                    167:                        if (n != len) {
                    168:                                fprintf(stderr, "%s: short write\n", ofile);
                    169:                                break;
                    170:                        }
                    171:                } else {
                    172:                        n = mio_write(oh, buf, len);
                    173:                        if (n != len) {
                    174:                                fprintf(stderr, "%s: disconnected\n", port1);
                    175:                                break;
                    176:                        }
                    177:                }
                    178:                if (dump) {
                    179:                        for (i = 0; i < len; i++) {
                    180:                                sep = (i % 16 == 15 || i == len - 1) ?
                    181:                                    '\n' : ' ';
                    182:                                fprintf(stderr, "%02x%c", buf[i], sep);
                    183:                        }
                    184:                }
                    185:        }
                    186:
                    187:        /* clean-up */
                    188:        if (port0)
                    189:                mio_close(ih);
                    190:        if (port1)
                    191:                mio_close(oh);
                    192:        if (ifile)
                    193:                close(ifd);
                    194:        if (ofile)
                    195:                close(ofd);
                    196:        return 0;
                    197: }