1 /*
2  * ***************************************************************************
3  * MALOC = < Minimal Abstraction Layer for Object-oriented C >
4  * Copyright (C) 1994-- Michael Holst
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * rcsid="$Id: main.c,v 1.13 2010/08/09 19:01:33 fetk Exp $"
21  * ***************************************************************************
22  */
23 
24 /*
25  * ***************************************************************************
26  * File:     bridge.c
27  *
28  * Purpose:  Socket-to-socket bridge.
29  *
30  * Notes:    The source and destination sockets can be any combination of
31  *           UNIX domain (AF_UNIX, AF_LOCAL) and internet (AF_INET) sockets.
32  *
33  * Author:   Michael Holst
34  * ***************************************************************************
35  */
36 
37 #include "maloc/maloc.h"
38 
39 #define VEMBED(rctag) VPRIVATE const char* rctag; \
40     static void* use_rcsid=(0 ? &use_rcsid : (void*)&rcsid);
41 VEMBED(rcsid="$Id: main.c,v 1.13 2010/08/09 19:01:33 fetk Exp $")
42 
43 /* int MAIN__(void) {}; */
44 
main(int argc,char * argv[])45 int main(int argc, char *argv[])
46 {
47     char inType[80], outType[80], hostname[64], buf[VMAX_BUFSIZE];
48     int  ok, inputWasFile, done, firstTime, bufsize;
49     Vio   *inSock, *outSock;
50 
51     inputWasFile = 0;
52     ok = 1;
53     if (argc == 4) {
54         strncpy(hostname,"localhost",sizeof(hostname));
55         fprintf(stderr,"%s: Starting up on host <%s>\n", argv[0], hostname);
56         if (!strcmp(argv[1],"-u2i")) {
57             strcpy(inType,"UNIX");
58             strcpy(outType,"INET");
59         } else if (!strcmp(argv[1],"-i2u")) {
60             strcpy(inType,"INET");
61             strcpy(outType,"UNIX");
62         } else if (!strcmp(argv[1],"-u2u")) {
63             strcpy(inType,"UNIX");
64             strcpy(outType,"UNIX");
65         } else if (!strcmp(argv[1],"-i2i")) {
66             strcpy(inType,"INET");
67             strcpy(outType,"INET");
68         } else if (!strcmp(argv[1],"-f2u")) {
69             strcpy(inType,"FILE");
70             strcpy(outType,"UNIX");
71             inputWasFile = 1;
72         } else if (!strcmp(argv[1],"-f2i")) {
73             strcpy(inType,"FILE");
74             strcpy(outType,"INET");
75             inputWasFile = 1;
76         } else ok = 0;
77     } else ok = 0;
78 
79     VJMPERR1( ok );
80 
81     /* start the Vio communication layer */
82     Vio_start();
83 
84     /* open the input socket */
85     if ( VNULL==(inSock=Vio_ctor(inType,"ASC",hostname,argv[2],"r")) ) {
86         fprintf(stderr,"%s: Problem open input socket <%s>\n",
87             argv[0],argv[2]);
88         VJMPERR1(0);
89     } else {
90         firstTime = 1;
91         done = 0;
92         while (!done) {
93 
94             /* do some extra stuff the first time */
95             if (firstTime) {
96                 firstTime = 0;
97 
98                 /* if input was a file, we just do one shot */
99                 if (inputWasFile) done = 1;
100 
101             /* must be non-file input; go to sleep for a bit */
102             } else {
103                 /* (don't need this since now do BLOCKing accept/connect) */
104                 /* Vsig_sleep(100); */
105             }
106 
107             /* call (blocking) accept on input socket */
108             if ( 0 > Vio_accept(inSock,0) ) {
109                 fprintf(stderr,"%s: Problem accept input socket <%s>\n",
110                     argv[0], argv[3]);
111                 VJMPERR1(0);
112             } else {
113 
114                 /* some i/o */
115                 fprintf(stderr,"%s: Hit on %s port <%s> from <%s>\n",
116                     argv[0],inType,inSock->file,inSock->rhost);
117 
118                 /* now that we have some data, open the output socket */
119                 if ( VNULL==(outSock=Vio_ctor(outType,"ASC",
120                   hostname,argv[3],"w")) ) {
121                     fprintf(stderr,"%s: Problem open output socket <%s>\n",
122                         argv[0], argv[3]);
123                     VJMPERR1(0);
124                 } else {
125 
126                     /* call (blocking) connect on output socket */
127                     if ( 0 > Vio_connect(outSock,0) ) {
128                         fprintf(stderr,"%s: Problem conn output socket <%s>\n",
129                             argv[0], argv[3]);
130                         VJMPERR1(0);
131                     } else {
132 
133                         /* some i/o */
134                         fprintf(stderr,"%s: Pass to %s port <%s> on <%s>\n",
135                             argv[0],outType,outSock->file,outSock->lhost);
136 
137                         /* grab input and write to output until done */
138                         memset(buf, '\0', sizeof(buf));
139                         while (0<(bufsize=Vio_read(inSock,buf,sizeof(buf)))) {
140                             VJMPERR2(bufsize==Vio_write(outSock,buf,bufsize));
141                             memset(buf, '\0', sizeof(buf));
142                         }
143 
144                         /* release the input subsocket and the output socket */
145                       VERROR2:
146                         Vio_connectFree(outSock);
147                     }
148                     /* close output socket */
149                     Vio_dtor(&outSock);
150                 }
151                 /* free the input subsocket */
152                 Vio_acceptFree(inSock);
153             }
154         }
155     }
156     /* close input socket */
157     Vio_dtor(&inSock);
158 
159     /* stop the Vio communication layer */
160     Vio_stop();
161 
162     /* return with no errors */
163     fprintf(stderr,"%s: Shutting down on host <%s>\n", argv[0], hostname);
164     return 1;
165 
166   VERROR1:
167     fprintf(stderr,"Usage: %s -u2i unixSocket inetSocket\n", argv[0]);
168     fprintf(stderr,"   or: %s -i2u inetSocket unixSocket\n", argv[0]);
169     fprintf(stderr,"   or: %s -u2u unixSocket unixSocket\n", argv[0]);
170     fprintf(stderr,"   or: %s -i2i inetSocket inetSocket\n", argv[0]);
171     fprintf(stderr,"   or: %s -f2u fileName   unixSocket\n", argv[0]);
172     fprintf(stderr,"   or: %s -f2i fileName   inetSocket\n", argv[0]);
173     return 0;
174 }
175 
176