1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % File:         PXK:PIPE-S.C
5 % Description:  pipe, slave mode
6 % Author:
7 % Created:
8 % Modified:
9 % Mode:         Text
10 % Package:
11 % Status:       Open Source: BSD License
12 %
13 % Redistribution and use in source and binary forms, with or without
14 % modification, are permitted provided that the following conditions are met:
15 %
16 %    * Redistributions of source code must retain the relevant copyright
17 %      notice, this list of conditions and the following disclaimer.
18 %    * Redistributions in binary form must reproduce the above copyright
19 %      notice, this list of conditions and the following disclaimer in the
20 %      documentation and/or other materials provided with the distribution.
21 %
22 % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 % THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 % PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR
26 % CONTRIBUTORS
27 % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 % POSSIBILITY OF SUCH DAMAGE.
34 %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 */
37 
38 #define _CRT_SECURE_NO_WARNINGS
39 
40 #include <windows.h>
41 #include <string.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #ifdef ALPHA
47 #define LONG __int64
48 #else
49 #define LONG long
50 #endif
51 
52 
53 #ifdef TEST
54 #define TEST_PRINT(fmt,p1,p2) pmelden(fmt,p1,p2)
55 #else
56 #define TEST_PRINT(fmt,p1,p2)
57 #endif
58 
59 HANDLE fe2lisp_read,fe2lisp_write, lisp2fe_read, lisp2fe_write;
60 static int slave_mode = 1;
61 
62 void my_popen_slave(int n);
63 
64 extern void my_puts(char *);
65 extern int my_psend(char,char *,int);
66 extern int my_preceive(char,char *,int);
67 extern int myWriteToNamedPipe(char *,int);
68 extern int myReadFromNamedPipe(char *,int);
69 extern void local_puts(char *);
70 extern int my_plocalcall(char *,int);
71 
72 extern LONG bruch_bruch;
73 
74 
75 //protocol:
76 //     c:   remote procedure call
77 //     a:   answer to rpc
78 //     r:   read request
79 //     d:   data reply to 'r'
80 //     b:   break
81 //     x:   exit
82 //     w:   write (data)
83 //     k:   ack to w
84 
85 void my_peek();
86 
who()87 char * who()
88    {
89       if(slave_mode) return("slave"); else return("master");
90    }
91 
pmelden(char * fmt,char * p1,char * p2)92 pmelden(char * fmt,char * p1, char * p2)
93    {
94       char str[100];
95       sprintf(str,fmt,who(),p1,p2);
96       if(slave_mode) puts(str); else my_puts(str);
97    }
98 
my_rpc(char * buf,int len)99 my_rpc(char * buf, int len)
100    {
101          TEST_PRINT("%s RPC call\n %s\n",buf,"");
102       my_psend('c',buf,len);
103       return(my_preceive('a',buf,len));
104    }
105 
my_popen_slave(int n)106 void my_popen_slave(int n)
107    {
108      char lbuf[10];
109        // transfer address of break control to master
110      sprintf(lbuf,"%lx",&bruch_bruch);
111 printf("adr bruch %s\n",lbuf);
112      my_psend('b',lbuf,strlen(lbuf));
113   }
114 
my_pexit()115 my_pexit()
116    {
117       char lbuf[8];
118       my_psend('x',lbuf,0);
119       //myDeleteNamedPipe();
120    }
121 
my_pwrite(char * buf,int len)122 my_pwrite(char * buf, int len)
123    {
124       int i,j; char lbuf[100];
125 
126       if((int)strlen(buf) > len) buf[len] = '\0';
127       printf("%s",buf);
128       j = my_psend('w',buf,len);
129       i = my_preceive('k',lbuf,100);
130       return(j);
131    }
132 
my_pread(char * buf,int len)133 my_pread(char * buf, int len)
134    {
135        int i;
136        my_psend('r',"",0);
137        i = my_preceive('d',buf, len);
138        buf[i] = '\0';
139        printf("%s\n",buf);
140        return(i);
141    }
142 
my_psend(char type,char * buf,int len)143 my_psend(char type, char * buf, int len)
144    {
145        int ret;
146        char lbuf[600];
147 
148        strncpy(lbuf,buf,len);
149 
150        lbuf[len] = type;
151           TEST_PRINT("%s sends: %s\n",lbuf,"");
152        ret=myWriteToNamedPipe(lbuf,len+1);
153        my_peek();
154        return(ret);
155    }
156 
my_preceive(char type,char * buf,int len)157 my_preceive(char type, char * buf, int len)
158    {
159      int ret,t,llen;
160      char lbuf[600];
161 
162          TEST_PRINT("%s waits for %s\n",(char*)&type,"");
163      next:
164        llen = myReadFromNamedPipe(lbuf, 600);
165        llen -- ; t = lbuf[llen]; lbuf[llen] = '\0';
166 
167        if (t == type)
168          {
169            strncpy(buf,lbuf,llen);
170              TEST_PRINT("%s received %s\n",&type,"");
171            return(llen);
172          };
173 
174              TEST_PRINT("%s received %s\n",(char*)&t,"");
175        if(t == 'x')  // exit
176           exit(0);
177        else if(t == 'w')
178          {
179            local_puts(lbuf);
180          }
181        else if(t == 'c')  // remote procedure call
182          {
183               ////printf("%s received RPC %s\n",lbuf,"");
184               TEST_PRINT("%s received RPC %s\n",lbuf,"");
185            ret=my_plocalcall(lbuf,llen);    // call local procedure
186               ////printf("%s returns from RPC %d\n","",ret);
187               TEST_PRINT("%s returns from RPC\n","","");
188            my_psend('a',lbuf,ret);    // result return
189          }
190        else
191         {
192           sprintf(lbuf," error: unexpected message >%c< instead of >%c<\n",t,type);
193           pmelden("%s %s\n",lbuf,"");
194         }
195       goto next;
196    }
197 
my_peek()198 void my_peek()
199    {
200        // handle messages with may come asynchronously
201 
202      int ret,t,llen;
203      char lbuf[600];
204 
205        if   (1) // (!PeekNamedPipe(the_named_pipe,lbuf,600,&llen,&l1,&l2)
206                 //|| llen<1)
207           {
208              TEST_PRINT("%s peek empty\n","","");
209              return;
210           }
211 
212        llen -- ; t = lbuf[llen]; lbuf[llen] = '\0';
213 
214            TEST_PRINT("%s peek sees message %s\n",(char*)&t, "");
215 
216        if (!(t == 'x' || t == 'c' || t == 'b' || (t == 'w' && ! slave_mode))) return;
217 
218            TEST_PRINT("%s peek processes message %s\n",(char*)&t, "");
219 
220        llen = myReadFromNamedPipe(lbuf, 600);
221 
222        if(t == 'x')  // exit
223           exit(0);
224        else if(t == 'c')  // remote procedure call
225          {
226            ret=my_plocalcall(lbuf,llen);    // call local procedure
227            my_psend('a',lbuf,ret);          // result return
228          }
229        else if(t == 'b')
230            bruch_bruch--;
231        else if(t == 'w')
232          {
233            local_puts(lbuf);
234          }
235     }
236 
237 
myWriteToNamedPipe(char * buf,int bytes)238 myWriteToNamedPipe(char * buf, int bytes)
239   {
240       DWORD  retCode;
241       DWORD bytesWritten;
242 
243       retCode = WriteFile (lisp2fe_write, buf, bytes,
244                      &bytesWritten, (LPOVERLAPPED)NULL);
245       FlushFileBuffers(lisp2fe_write);
246 
247       return((int)bytesWritten);
248  }
249 
myReadFromNamedPipe(char * buf,int bytes)250 myReadFromNamedPipe(char * buf, int bytes)
251   {
252 
253       DWORD  retCode;
254       DWORD bytesRead;
255 
256       while(!(retCode = ReadFile (fe2lisp_read, buf, bytes,
257                       &bytesRead, (LPOVERLAPPED)NULL))) Sleep(500);
258 
259       return((int) bytesRead);
260   }
261