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

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);
        !           101:                        if (ifd < 0) {
        !           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);
        !           111:                        if (ofd < 0) {
        !           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:
        !           144:        if (pledge("stdio", NULL) < 0)
        !           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;
        !           153:                        if (len < 0) {
        !           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: }