Merge from vendor branch TEXINFO:
[dragonfly.git] / share / examples / isdn / contrib / isdntelmux.c
1 /*
2  * Copyright (c) 1999 Michael Reifenberger (Michael@Reifenberger.com). 
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *---------------------------------------------------------------------------
27  *
28  *      i4btemux - record while playing
29  *      ===============================
30  *
31  * $FreeBSD: src/share/examples/isdn/contrib/isdntelmux.c,v 1.1.2.1 2001/08/10 14:59:48 obrien Exp $
32  * $DragonFly: src/share/examples/isdn/contrib/isdntelmux.c,v 1.2 2003/06/17 04:36:57 dillon Exp $
33  *
34  *----------------------------------------------------------------------------*/
35
36 #include<stdio.h>
37 #include<stdarg.h>
38 #include<signal.h>
39 #include<errno.h>
40 #include<string.h>
41 #include<stdlib.h>
42 #include<unistd.h>
43 #include<fcntl.h>
44 #include<ctype.h>
45 #include<sys/stat.h>
46 #include<sys/wait.h>
47 #include<sys/ioctl.h>
48 #include<sys/types.h>
49 #include<sys/time.h>
50 #include<sys/param.h>
51 #include<machine/i4b_tel_ioctl.h>
52
53 // DECL DEFS
54 #define BUFLEN 2048
55 #define MAXBLOCKS_DEFAULT 23
56
57 // DECL VARS
58 int ibytes = 0;
59 int obytes = 0;
60 int maxbytes = (BUFLEN * MAXBLOCKS_DEFAULT);
61
62 int xfd = -1, xact = 0;
63 int ifd = -1, iact = 0;
64 int ofd = -1;
65 FILE *dfp = NULL;
66 int opt_dbg = 0;
67 int maxfd = 0;
68 fd_set set;
69 struct timeval timeout;
70 char nambuf[PATH_MAX];
71 int ch;
72
73 // DECL FUNC
74 void ifd_hdlr( void);
75 void xfd_hdlr( void);
76 void usage( void);
77 void dbg( char *fmt, ... );
78
79 // DEF FUNC
80 int main (int argc, char **argv) {
81   int dummy;
82   int x = -1;
83
84   dfp = stderr;
85   while( ( ch = getopt( argc, argv, "x:i:o:b:D:")) != -1 ){
86     switch(ch){
87       case 'b':
88         x = atoi(optarg);
89         maxbytes = x * BUFLEN;
90         break;
91       case 'i':
92         ifd = open( optarg, O_RDONLY );
93         iact = 1;
94         break;
95       case 'o':
96         ofd = open( optarg, O_WRONLY|O_TRUNC|O_CREAT );
97         break;
98       case 'x':
99         xfd = open( optarg, O_RDWR );
100         xact = 1;
101         break;
102       case 'D':
103         opt_dbg = 1;
104         if( (dfp = fopen( optarg, "w" )) < 0) {
105           dfp = stderr;
106           dbg("Err for opening %s\n", optarg);
107           exit(1);
108         }
109         break;
110       case '?':
111       default:
112         usage();
113         break;
114     }
115   }
116   if( ( xfd < 0 ) || ( ifd < 0 ) || ( ofd < 0 ) ) {
117     dbg("Err opening one ore more Files.\n");
118     dbg("xfd: %d, ifd: %d, ofd: %d\n", xfd, ifd, ofd );
119     usage();
120   }
121
122   if((x = ioctl(xfd, I4B_TEL_EMPTYINPUTQUEUE, &dummy)) < 0){
123     dbg("Err I4B_TEL_EMPTYINPUTQUEUE\n");
124   }
125
126   while( (iact == 1) || ( (obytes < maxbytes) && (xact == 1) ) ){
127     FD_ZERO( &set);
128     if( iact == 1){
129       FD_SET( ifd, &set);
130       if( ifd > maxfd)
131         maxfd = ifd; 
132       dbg("FSET ifd\n");
133     }
134     if( xact == 1){
135       FD_SET( xfd, &set);
136       if( xfd > maxfd)
137         maxfd = xfd; 
138       dbg("FSET xfd\n");
139     }
140     x=select( maxfd+1, &set, NULL, NULL, NULL);
141     if( x > 0){
142       if( (iact == 1) && FD_ISSET( ifd, &set) ){
143         ifd_hdlr();
144       }
145       if( (xact == 1) && FD_ISSET( xfd, &set) ){
146         xfd_hdlr();
147       }
148     }
149   }
150   dbg("exit0\n");
151   return(0);
152 }
153
154 void ifd_hdlr( void) {
155   int x;
156   unsigned char buf[BUFLEN];
157
158   x = read( ifd, buf, BUFLEN); 
159   dbg("ifd read %d bytes\n", x);
160   if( x > 0 ){
161     write( xfd, buf, x);
162     ibytes += x;
163     dbg("xfd %d bytes written to %d\n", x, ibytes);
164   } else {
165     iact = 0;
166   }
167 }
168
169 void xfd_hdlr( void) {
170   int x;
171   unsigned char buf[BUFLEN];
172
173   x = read( xfd, buf, BUFLEN);
174   dbg("xfd read %d bytes\n", x);
175   if( x > 0){
176     write( ofd, buf, x);
177     obytes += x;
178     dbg("ofd %d bytes written to %d\n", x, obytes);
179   } else {
180     xact = 0;
181   }
182 }
183
184 void usage( void) {
185   fprintf(dfp, "isdntelmux V.1\n");
186   fprintf(dfp, "usage: isdntelmux -x device -i ifile -o ofile [-b blocks]\n");
187   exit(1);
188 }
189
190 void dbg( char *fmt, ... ) {
191   va_list ap;
192
193   if( opt_dbg == 0 )
194     return;
195   va_start( ap, fmt );
196   vfprintf( dfp, fmt, ap);
197   va_end(ap);
198 }