Annotation of OpenXM/src/kan96xx/plugin/oxmisc.c, Revision 1.23
1.23 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc.c,v 1.22 2004/09/17 07:27:28 takayama Exp $ */
1.1 maekawa 2: #include <stdio.h>
3: #include <sys/types.h>
4: #include <sys/stat.h>
5: #include <sys/socket.h>
6: #include <sys/time.h>
7: #include <netinet/in.h>
8: #include <netdb.h>
9: #include <fcntl.h>
10: #include <stdlib.h>
11: #include <unistd.h>
12: #include <signal.h>
13: #include <setjmp.h>
1.19 takayama 14: #include <errno.h>
1.5 takayama 15: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
16: /* It is also defined in oxmisc2.c */
17: FILE *MyErrorOut = NULL;
1.1 maekawa 18:
19: /* Include files to understand object */
20: #include "../Kan/datatype.h"
21: #include "../Kan/stackm.h"
22: #include "../Kan/extern.h"
23:
24: #include "ox_kan.h"
25:
26: #define READBUFSIZE 5000
27:
1.8 takayama 28: int OxVersion = 200012030;
1.1 maekawa 29: int UseOXPacketSerial = 1;
30: int SerialOX = 1;
31: extern int Quiet;
32:
33: static char *OxPortFileName = ".ox.dummy";
34:
35:
36: int readOneByte(int fd) /* blocking */
37: {
38: static char data[1];
39: int size;
40: int ans;
41: int watch = 1;
42:
1.5 takayama 43: SET_MYERROROUT;
1.1 maekawa 44: if (fd < 0) {
45: fprintf(MyErrorOut,"readOneByte fd < 0 ??? .\n");
46: return(-1);
47: }
48:
49: if (oxSocketSelect0(fd,-1)) { /* block */
50: size = read(fd,data,1);
51: if (size == 0) {
1.7 takayama 52: fprintf(MyErrorOut,"oxSocketSelect0() returns 1, but there is no data. Your peer may be killed.\n");
1.1 maekawa 53: return(-1);
54: }
55: return(data[0]);
56: }else{
57: fprintf(MyErrorOut,"readOneByte: select error in block mode. Retrying.\n");
58: return(-1);
59: }
60: }
61:
62: int readOneByte_org(int fd) /* blocking */
63: {
64: static char data[READBUFSIZE];
65: static int thisFd = -1;
66: static int from = 0;
67: static int to = 0;
68: int size;
69: int ans;
70: int watch = 1;
71:
1.5 takayama 72: SET_MYERROROUT;
1.1 maekawa 73: if ((thisFd == -1) && (fd >= 0)) {thisFd = fd;}
74: if (fd < 0) {
75: fprintf(MyErrorOut,"readOneByte fd < 0 ??? .\n");
76: return(-1);
77: }
78:
79: if (fd != thisFd) {
80: fprintf(MyErrorOut,"readOneByte can be used only for one fd.\n");
81: fflush(NULL);
82: return(-1);
83: }
84: if (to > from) {
85: ans = data[from];
86: from++;
87: if (watch) {
88: printf("%2x ",ans);
89: fflush(stdout);
90: }
91: return(ans);
92: }
93:
94: while (1) {
95: if (oxSocketSelect0(fd,-1)) { /* block */
96: size = read(fd,data,READBUFSIZE-1);
97: if (size == 0) {
1.9 takayama 98: fprintf(MyErrorOut,"oxSocketSelect0() returns 1, but there is no data. Your peer may be killed.\n");
99: return(-1);
1.1 maekawa 100: }
101: from = 0;
102: to = size;
103: return(readOneByte(fd));
104: }else{
105: fprintf(MyErrorOut,"readOneByte: select error in block mode. Retrying.\n"); }
106: }
107: }
108:
109: int oxfdGetInt32(int fd)
110: {
111: char d[4];
112: int i;
113: for (i=0; i<4; i++) {
114: d[i] = readOneByte(fd);
115: }
116: return(ntohl(* ( (int *)d)));
117: }
118:
119: int oxGetInt32(ox_stream ostream)
120: {
121: char d[4];
122: int i;
123: for (i=0; i<4; i++) {
124: d[i] = fp2fgetc(ostream);
125: }
126: return(ntohl(* ( (int *)d)));
127: }
128: int oxGetCMOInt32(ox_stream ostream)
129: {
130: int id;
1.5 takayama 131: SET_MYERROROUT;
1.1 maekawa 132: id = oxGetInt32(ostream);
133: if (id != CMO_INT32) {
134: fprintf(MyErrorOut,"It is not CMO_INT32.\n");
135: return(0);
136: }
137: return(oxGetInt32(ostream));
138: }
139: char *oxGetCMOString(ox_stream ostream) {
140: int id;
141: int size;
142: char *r;
143: int i;
1.5 takayama 144: SET_MYERROROUT;
1.1 maekawa 145: id = oxGetInt32(ostream);
146: if (id != CMO_STRING) {
147: fprintf(MyErrorOut,"It is not CMO_STRING.\n");
148: return(NULL);
149: }
150: size = oxGetInt32(ostream);
151: if (size <0) {
152: return(NULL);
153: }else{
154: r = (char *)mymalloc(size+1);
155: for (i=0; i<size; i++) {
156: r[i] = fp2fgetc(ostream);
157: }
158: r[size] = '\0';
159: return(r);
160: }
161: }
162:
163: void oxfdSendSyncBall(int fd)
164: {
165: oxfdSendOXheader(fd,OX_SYNC_BALL,SerialOX++);
166: }
167:
168: void oxSendSyncBall(ox_stream os)
169: {
170: oxSendOXheader(os,OX_SYNC_BALL,SerialOX++);
171: }
172:
173: int oxWaitSyncBall(ox_stream ostream)
174: {
175: int sss;
176: int mtag;
177: while ((mtag = oxGetOXheader(ostream,&sss)) != OX_SYNC_BALL) {
178: fprintf(stderr,"Looking for the next message tag. mtag=%d\n",mtag);
1.9 takayama 179: /* or stdout */
1.1 maekawa 180: fflush(NULL);
181: }
182: }
183:
184: int oxWaitSyncBall_org(ox_stream ostream)
185: {
186: int mtag;
187: char data[4];
188: int c;
1.5 takayama 189: SET_MYERROROUT;
1.1 maekawa 190: data[0] = data[1] = data[2] = data[3] = 0xff;
191: while (1) {
192: /* This part should be revised so that this part understands
193: the cmo format.
1.9 takayama 194: */
1.1 maekawa 195:
196: if ((c = fp2fgetc(ostream)) < 0) {
197: /* never use read directory. readOneByte() is buffers every thing. */
198: fprintf(MyErrorOut,"End of file.\n");
199: return(-1);
200: }
201: data[0] = data[1];
202: data[1] = data[2];
203: data[2] = data[3];
204: data[3] = (char)c;
205: mtag = ntohl(*((int *)(data)));
206: if (mtag == OX_SYNC_BALL) {
207: printf("Found the OX_SYNC_BALL. \n");
208: fflush(NULL);
209: return(mtag);
210: }
211: fprintf(stderr,"Looking for the next message tag.. %2x, mtag=%d\n",c,mtag);
1.9 takayama 212: /* or stdout */
1.1 maekawa 213: fflush(NULL);
214: }
215: }
216:
217:
218: void oxfdSendCmoNull(int fd)
219: {
220: char data[4];
221: *((int *)&data[0]) = htonl(CMO_NULL);
222: write(fd,data,4);
223: fflush((FILE *)NULL);
224: }
225: void oxSendCmoNull(ox_stream os)
226: {
227: char data[4];
228: *((int *)&data[0]) = htonl(CMO_NULL);
229: fp2write(os,data,4);
230: fp2fflush(os);
231: }
232:
233: void oxSendCmoError(ox_stream os)
234: {
235: char data[4];
236: *((int *)&data[0]) = htonl(CMO_ERROR);
237: fp2write(os,data,4);
238: fp2fflush(os);
239: }
240:
241: void oxSendCmoError2(ox_stream os,char *s)
242: {
243: char data[4];
244: *((int *)&data[0]) = htonl(CMO_ERROR2);
245: fp2write(os,data,4);
246: fp2fflush(os);
247: oxSendCmoString(os,s);
248: }
249:
250: void oxfdSendInt32(int fd,int k)
251: {
252: char data[4];
253: *((int *)&data[0]) = htonl(k);
254: write(fd,data,4);
255: fflush((FILE *)NULL);
256: }
257: void oxSendInt32(ox_stream os,int k)
258: {
259: char data[4];
260: *((int *)&data[0]) = htonl(k);
261: fp2write(os,data,4);
262: fp2fflush(os);
263: }
264:
265: void oxfdSendCmoInt32(int fd,int k)
266: {
267: char data[4*2];
268: *((int *)&data[0]) = htonl(CMO_INT32);
269: *((int *)&data[4]) = htonl(k);
270: write(fd,data,4*2);
271: fflush((FILE *)NULL);
272: }
273: void oxSendCmoInt32(ox_stream os,int k)
274: {
275: char data[4*2];
276: *((int *)&data[0]) = htonl(CMO_INT32);
277: *((int *)&data[4]) = htonl(k);
278: fp2write(os,data,4*2);
279: fp2fflush(os);
280: }
281: void oxfdSendCmoString(int fd,char *s)
282: {
283: char data[4*2];
284: int n;
285: if (s == NULL) n = 0;
286: else {
287: n = strlen(s);
288: }
289: *((int *)&data[0]) = htonl(CMO_STRING);
290: *((int *)&data[4]) = htonl(n);
291: write(fd,data,4*2);
292: if (s != NULL) {
293: write(fd,s,n);
294: }
295: fflush((FILE *)NULL);
296: }
297:
298: void oxSendCmoString(ox_stream os,char *s)
299: {
300: char data[4*2];
301: int n;
302: if (s == NULL) n = 0;
303: else {
304: n = strlen(s);
305: }
306: *((int *)&data[0]) = htonl(CMO_STRING);
307: *((int *)&data[4]) = htonl(n);
308: fp2write(os,data,4*2);
309: if (s != NULL) {
310: fp2write(os,s,n);
311: }
312: fp2fflush(os);
313: }
314:
315:
316:
317: void oxReqPushString(ox_stream os, char *s)
318: {
319: oxSendOXheader(os,OX_DATA,SerialOX++);
320: oxSendCmoString(os,s);
321: }
322:
323: void oxSendResultOfControlInt32(int fd,int i)
324: {
325: char data[4*2];
326: oxfdSendOXheader(fd,OX_DATA,SerialOX++);
327: *((int *)&data[0]) = htonl(CMO_INT32);
328: *((int *)&data[4]) = htonl(i);
329: write(fd,data,4*2);
330: fflush((FILE *)NULL);
331: }
332:
333: void oxSendResultOfControl(int fd)
334: {
335: char data[4*1];
336: oxfdSendOXheader(fd,OX_DATA,SerialOX++);
337: *((int *)&data[0]) = htonl(CMO_NULL);
338: write(fd,data,4*1);
339: fflush((FILE *)NULL);
340: }
341:
342:
343:
344: void oxSendMathCap(ox_stream os,struct mathCap *mathcap)
345: {
1.4 takayama 346: int i,n,infosize,ncmo;
1.1 maekawa 347: struct object mathinfo;
348: /* printf("ox sending mathcap\n"); fflush(stdout); */
349: mathinfo = *((struct object *)(mathcap->infop));
350: infosize = getoaSize(mathinfo);
351:
352: oxSendInt32(os,CMO_MATHCAP);
353:
354: oxSendInt32(os,CMO_LIST);
355: oxSendInt32(os,3);
356:
357: /* [0] */
358: oxSendInt32(os,CMO_LIST);
359: oxSendInt32(os,infosize);
360: oxSendCmoInt32(os,KopInteger(getoa(mathinfo,0)));
361: for (i=1; i<infosize; i++) {
362: oxSendCmoString(os,KopString(getoa(mathinfo,i)));
363: }
364:
365: /* [1] */
366: oxSendInt32(os,CMO_LIST);
367: oxSendInt32(os,mathcap->smSize);
368: n = mathcap->smSize;
369: for (i=0; i<n; i++) {
370: oxSendCmoInt32(os,(mathcap->sm)[i]);
371: }
372:
373: /* [2] */
374: oxSendInt32(os,CMO_LIST);
1.4 takayama 375: n = mathcap->oxSize;
376: oxSendInt32(os,n);
1.1 maekawa 377:
378: oxSendInt32(os,CMO_LIST);
1.4 takayama 379: oxSendInt32(os,2);
1.1 maekawa 380: for (i=0; i<n; i++) {
1.4 takayama 381: /* OX_DATA_xxx */
1.1 maekawa 382: oxSendCmoInt32(os,(mathcap->ox)[i]);
1.4 takayama 383: /* OX_DATA_xxx tags. In case of CMO, it is CMO tags. */
384: oxSendInt32(os,CMO_LIST);
385: oxSendInt32(os,mathcap->n);
386: ncmo = mathcap->n;
387: for (i=0; i<ncmo; i++) {
388: oxSendCmoInt32(os,(mathcap->cmo)[i]);
389: /* printf("i=%d %d, ",i,(mathcap->cmo)[i]); */
390: }
1.1 maekawa 391: }
392: /* printf("\n"); fflush(stdout); */
393: }
394:
395: void oxReqMathCap(ox_stream os) {
396: oxSendOXheader(os,OX_COMMAND,SerialOX++);
397: oxSendInt32(os,SM_mathcap);
398: fp2fflush(os);
399: }
400:
401: void oxReqSetMathCap(ox_stream os,struct mathCap *mathcap) {
402: oxSendOXheader(os,OX_DATA,SerialOX++);
403: oxSendMathCap(os,mathcap);
404: oxSendOXheader(os,OX_COMMAND,SerialOX++);
405: oxSendInt32(os,SM_setMathCap);
406: fp2fflush(os);
407: }
408: void oxReqPops(ox_stream os,int n) {
409: oxSendOXheader(os,OX_DATA,SerialOX++);
410: oxSendCmoInt32(os,n);
411: oxSendOXheader(os,OX_COMMAND,SerialOX++);
412: oxSendInt32(os,SM_pops);
413: fp2fflush(os);
414: }
415: void oxReqSetName(ox_stream os,char *s) {
416: oxSendOXheader(os,OX_DATA,SerialOX++);
417: oxSendCmoString(os,s);
418: oxSendOXheader(os,OX_COMMAND,SerialOX++);
419: oxSendInt32(os,SM_setName);
420: fp2fflush(os);
421: }
422: void oxReqEvalName(ox_stream os,char *s) {
423: oxSendOXheader(os,OX_DATA,SerialOX++);
424: oxSendCmoString(os,s);
425: oxSendOXheader(os,OX_COMMAND,SerialOX++);
426: oxSendInt32(os,SM_evalName);
427: fp2fflush(os);
428: }
429:
430: void oxReqExecuteStringByLocalParser(ox_stream os,char *s)
431: {
432: oxSendOXheader(os,OX_DATA,SerialOX++);
433: oxSendCmoString(os,s);
434: oxSendOXheader(os,OX_COMMAND,SerialOX++);
435: oxSendInt32(os,SM_executeStringByLocalParser);
436: fp2fflush(os);
437: }
438:
439: void oxReqExecuteFunction(ox_stream os,char *s)
440: {
441: oxSendOXheader(os,OX_DATA,SerialOX++);
442: oxSendCmoString(os,s);
443: oxSendOXheader(os,OX_COMMAND,SerialOX++);
444: oxSendInt32(os,SM_executeFunction);
445: fp2fflush(os);
446: }
447:
1.20 takayama 448: void oxReqExecuteFunctionWithOptionalArgument(ox_stream os,char *s)
449: {
450: oxSendOXheader(os,OX_DATA,SerialOX++);
451: oxSendCmoString(os,s);
452: oxSendOXheader(os,OX_COMMAND,SerialOX++);
453: oxSendInt32(os,SM_executeFunctionWithOptionalArgument);
454: fp2fflush(os);
455: }
456:
1.1 maekawa 457:
458: void oxReqPopString(ox_stream os)
459: {
460: oxSendOXheader(os,OX_COMMAND,SerialOX++);
461: oxSendInt32(os,SM_popString);
462: fp2fflush(os);
463: }
464:
465: void oxReqSingleOperand(ox_stream os,int smtag)
466: {
467: oxSendOXheader(os,OX_COMMAND,SerialOX++);
468: oxSendInt32(os,smtag);
469: fp2fflush(os);
470: }
471:
472:
473: void oxReqControlResetConnection(int fd) {
474: oxfdSendOXheader(fd,OX_COMMAND,SerialOX++);
475: oxfdSendInt32(fd,SM_control_reset_connection);
476: fflush(NULL);
477: }
478:
479: void oxReqControlKill(int fd) {
480: oxfdSendOXheader(fd,OX_COMMAND,SerialOX++);
481: oxfdSendInt32(fd,SM_control_kill);
482: fflush(NULL);
483: }
484:
485: void oxReqPopCMO(ox_stream os) {
486: oxSendOXheader(os,OX_COMMAND,SerialOX++);
487: oxSendInt32(os,SM_popCMO);
488: fp2fflush(os);
489: }
490:
491:
492: int oxGetResultOfControlInt32(int fd) {
493: int k; int sss;
1.5 takayama 494: SET_MYERROROUT;
1.1 maekawa 495: k = oxfdGetOXheader(fd,&sss);
496: if (k != OX_DATA) {
497: fprintf(MyErrorOut,"oxGetResultOfControlInt32: wrong header.");
498: return(-1);
499: }
500: k = oxfdGetInt32(fd); /* CMO_INT32 */
501: k = oxfdGetInt32(fd);
502: return(k);
503: }
504:
505: int oxclientMultiSelect(oxclientp clients[],int dataready[],
1.9 takayama 506: int controlready[], int size, int t)
1.1 maekawa 507: {
508: int i, ddd;
509: int fd;
510: int humanfd = 0;
511: fd_set readfds;
512: struct timeval timeout;
513:
1.5 takayama 514: SET_MYERROROUT;
1.1 maekawa 515: /** printf("(1)"); fflush(NULL); */
516: FD_ZERO(&readfds);
517: timeout.tv_sec = 0;
518: timeout.tv_usec = (long) t;
519:
520: ddd = 0; fd = 0;
521: for (i=0; i<size; i++) {
522: dataready[i] = controlready[i] = 0;
523: }
524: for (i=0; i<size; i++) {
525: if (clients[i]->humanio) {
526: fd = (fd<humanfd?humanfd:fd);
527: FD_SET(humanfd,&readfds);
528: if (oxSocketSelect0(humanfd,0)) {
1.9 takayama 529: ddd = dataready[i] = 1; controlready[i] = 0;
1.1 maekawa 530: }else{
1.9 takayama 531: dataready[i] = 0; controlready[i] = 0;
1.1 maekawa 532: }
533: }else{
1.9 takayama 534: if (clients[i]->controlport < 0) { /* For RFC_101 */
535: controlready[i] = 0;
536: }else{
537: fd = (fd<clients[i]->controlfd?clients[i]->controlfd:fd);
538: FD_SET(clients[i]->controlfd,&readfds);
539: if (oxSocketSelect0(clients[i]->controlfd,0)) {
540: ddd = controlready[i] = 1;
541: }else{
542: controlready[i] = 0;
543: }
544: }
1.1 maekawa 545: if (clients[i]->datafp2 != NULL) {
1.9 takayama 546: fd = (fd<clients[i]->datafp2->fd?clients[i]->datafp2->fd:fd);
547: FD_SET(clients[i]->datafp2->fd,&readfds);
548: if (fp2select(clients[i]->datafp2,0)) {
549: ddd = dataready[i] = 1;
550: }else{
551: dataready[i] = 0;
552: }
1.1 maekawa 553: }else{
1.9 takayama 554: dataready[i] = 0;
1.1 maekawa 555: }
556: }
557: }
558: if (t > 0 ) {
559: if (ddd) return(1);
560: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
561: fprintf(MyErrorOut,"error");
562: return(-1);
563: }
564: return(oxclientMultiSelect(clients, dataready, controlready,size,0));
565: }else if (t == 0) {
566: return(ddd);
567: }else {
568: /** printf("(2)"); fflush(NULL); */
569: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
570: fprintf(MyErrorOut,"error");
571: return(-1);
572: }
573: /** printf("(3)"); fflush(NULL); */
574: return(oxclientMultiSelect(clients, dataready, controlready,size,0));
575: }
576: }
577:
578: int oxGetControl(oxclientp client)
1.9 takayama 579: /* synchronized. */
1.1 maekawa 580: {
581: int ans;
582: ox_stream os;
583: switch (client->cstate) {
584: case 1:
585: ans = oxGetResultOfControlInt32(client->controlfd);
586: client->cstate = 0;
587: return(ans);
588: default:
589: fprintf(MyErrorOut,"oxGet: unknown cstate.\n");
590: client->cstate = -1;
591: return(-1);
592: }
593:
594: return(-1);
595: }
596:
597: int oxInitClient(oxclientp client)
598: {
599: client->datafp2 = NULL;
600: client->dataport = 0;
601: client->controlport = 0;
602: client->controlfd = 0;
603: client->humanio = 0;
604: client->dstate = 0;
605: client->cstate = 0;
606: client->id = -1;
607: client->mathcapObjp = NULL;
608: client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
609: client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
1.15 takayama 610: client->engineID = -1;
1.1 maekawa 611: return(0);
612: }
613:
614: int oxIsThereErrorClient(oxclientp client) {
615: if (client == NULL) return(1);
616: if (client->dstate == -1) return(1);
617: if (client->cstate == -1) return(1);
618: return(0);
619: }
620:
1.23 ! takayama 621: oxclientp oxCreateClient(char *sname,int portStream,int portControl,
! 622: char *passControl, char *passData)
1.9 takayama 623: /* you also need to change oxCreateClient2. */
1.1 maekawa 624: {
625: int v = 0;
626: int fdControl = -1;
627: int fdStream = -1;
628: oxclientp client;
629: int controlByteOrder, engineByteOrder;
630: v = !Quiet;
631: if (portControl != -1) {
632: fdControl = socketConnect(sname,portControl);
633: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
634: }
635: if (portStream != -1) {
636: sleep(1); /* wait */
637: fdStream = socketConnect(sname,portStream);
638: if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
639: }
640:
641: if (fdStream == -1 || fdControl == -1) {
642: fprintf(stderr,"\nOpen error in oxCreateClient.\n");
643: return(NULL);
1.23 ! takayama 644: }
! 645:
! 646: if (passControl != NULL) {
! 647: if (v) fprintf(stderr,"Sending password %s for the control channel.\n",
! 648: passControl);
! 649: if (write(fdControl,passControl,strlen(passControl)+1) < 0) {
! 650: fprintf(stderr,"oxCreateClient(): failed to send passControl.\n");
! 651: return(NULL);
! 652: }
! 653: }
! 654: if (passData != NULL) {
! 655: if (v) fprintf(stderr,"Sending password %s for the data channel.\n",
! 656: passData);
! 657: if (write(fdStream,passData,strlen(passData)+1) < 0) {
! 658: fprintf(stderr,"oxCreateClient(): failed to send passData.\n");
! 659: return(NULL);
! 660: }
1.1 maekawa 661: }
662:
663: controlByteOrder = oxSetByteOrder(fdControl);
664: if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9 takayama 665: (controlByteOrder == 0? "network byte order":
666: (controlByteOrder == 1? "little indican":
667: "big indian")));
1.1 maekawa 668: engineByteOrder = oxSetByteOrder(fdStream);
669: if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9 takayama 670: (engineByteOrder == 0? "network byte order":
671: (engineByteOrder == 1? "little indican":
672: "big indian")));
1.1 maekawa 673:
674: client = (oxclientp) mymalloc(sizeof(oxclient));
675: oxInitClient(client);
676: client->datafp2 = fp2open(fdStream);
677: if (client->datafp2 == NULL) {
678: fprintf(stderr,"oxCreateClient(): fp2open(fd) failed.\n");
679: return(NULL);
680: }
681: client->dataport = portStream;
682: client->controlport = portControl;
683: client->controlfd = fdControl;
1.13 takayama 684: client->id = oxGetClientID();
1.1 maekawa 685: client->type = CLIENT_SOCKET; /* socket */
686: client->engineByteOrder = engineByteOrder;
687: client->controlByteOrder = controlByteOrder;
688: return(client);
689: }
690:
691: oxclientp oxCreateClientFile(char *fname,char *mode,char *controlName,char *cmode)
692: {
693: static int clnum = 0x8000;
694: int v = 0;
695: int fdControl = -1;
696: int fdStream = -1;
697: oxclientp client;
698: v = 1;
699: if (strcmp(mode,"w") == 0) {
700: fdStream = creat(fname,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
701: if (fdStream < 0) {
702: fprintf(stderr,"\nCreat failed for %s\n",fname); return(NULL);
703: }
704: }else if (strcmp(mode,"r")==0) {
705: fdStream = open(fname,O_RDONLY);
706: if (fdStream < 0) {
707: fprintf(stderr,"\nOpen failed for %s\n",fname); return(NULL);
708: }
709: }else {
710: fprintf(stderr,"\nThe mode %s is not supported.\n",mode); return(NULL);
711: }
712:
713: if (strcmp(cmode,"w") == 0) {
714: fdControl = creat(controlName,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
715: if (fdControl < 0) {
716: fprintf(stderr,"\nCreat failed for %s\n",controlName); return(NULL);
717: }
718: }else if (strcmp(cmode,"r")==0) {
719: fdControl = open(controlName,O_RDONLY);
720: if (fdControl < 0) {
721: fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
722: }
723: }else if (strcmp(cmode,"rw")==0) {
724: fdControl = open(controlName,O_RDWR);
725: if (fdControl < 0) {
726: fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
727: }
728: }else {
729: fprintf(stderr,"\nThe mode %s is not supported.\n",cmode); return(NULL);
730: }
731:
732:
733: client = (oxclientp) mymalloc(sizeof(oxclient));
734: oxInitClient(client);
735: client->datafp2 = fp2open(fdStream);
736: if (client->datafp2 == NULL) {
737: fprintf(stderr,"oxCreateClientFile(): fp2open(fd) failed.\n");
738: return(NULL);
739: }
740: client->dataport = 0;
741: client->controlport = 0;
742: client->controlfd = fdControl;
743: client->id = clnum; clnum++;
744: client->type = CLIENT_FILE;
745: client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
746: client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
747: return(client);
748: }
749:
750: void oxSendOXheader_generic(int type,int fd,ox_stream ox,
1.9 takayama 751: int k,int serial)
1.1 maekawa 752: {
753: static int ss = 0;
754: extern int UseOXPacketSerial;
755: if (serial >= 0) ss = serial;
756: else ss++;
757: if (ss < 0) ss=0;
758: if (type == 0) { /* fd */
759: oxfdSendInt32(fd,k);
760: if (UseOXPacketSerial) oxfdSendInt32(fd,ss);
761: }else {
762: oxSendInt32(ox,k);
763: if (UseOXPacketSerial) oxSendInt32(ox,ss);
764: }
765: }
766: void oxSendOXheader(ox_stream ostream,int k,int serial) {
767: oxSendOXheader_generic(1,-1,ostream,k,serial);
768: }
769: void oxfdSendOXheader(int fd,int k,int serial) {
770: oxSendOXheader_generic(0,fd,(ox_stream) NULL,k,serial);
771: }
772:
773: int oxfdGetOXheader(int fd,int *sss)
774: {
775: char d[4];
776: int i;
777: int m;
778:
779: for (i=0; i<4; i++) {
780: d[i] = readOneByte(fd);
781: }
782: m = ntohl(* ( (int *)d));
783: *sss = -1;
784: if (UseOXPacketSerial) {
785: for (i=0; i<4; i++) {
786: d[i] = readOneByte(fd);
787: }
788: *sss = ntohl(* ( (int *)d));
789: }
790: return(m);
791: }
792:
793: int oxGetOXheader(ox_stream ostream,int *sss)
794: {
795: char d[4];
796: int m;
797: int i;
798:
799: unlockCtrlCForOx(); /* temporary unlock */
800: while (fp2select(ostream,1000) == 0) ;
801: restoreLockCtrlCForOx();
802:
803: for (i=0; i<4; i++) {
804: d[i] = fp2fgetc(ostream);
805: }
806: m = ntohl(* ( (int *)d));
807: *sss = -1;
808: if (UseOXPacketSerial) {
809: for (i=0; i<4; i++) {
810: d[i] = fp2fgetc(ostream);
811: }
812: *sss = ntohl(* ( (int *)d));
813: }
814: return(m);
815: }
816:
817:
818: oxWritePortFile(int func,int port,char *fname) {
819: char name[1024];
820: FILE *fp;
821: strcpy(name,fname);
822: if (func == 0) {
823: strcat(name,".control");
824: fp = fopen(name,"w");
825: fprintf(fp,"%05d\n",port);
826: fclose(fp);
827: }else {
828: strcat(name,".data");
829: fp = fopen(name,"w");
830: fprintf(fp,"%05d\n",port);
831: fclose(fp);
832: }
833: }
834: oxReadPortFile(int func,char *fname) {
835: int port = 0;
836: char name[1024];
837: FILE *fp;
838: strcpy(name,fname);
839: if (func == 0) {
840: strcat(name,".control");
841: fp = fopen(name,"r");
842: fscanf(fp,"%d",&port);
843: fclose(fp);
844: }else {
845: strcat(name,".data");
846: fp = fopen(name,"r");
847: fscanf(fp,"%d",&port);
848: fclose(fp);
849: }
850: return(port);
851: }
852: char *oxGenPortFile(void) {
853: char *fname;
854: time_t tt;
855: char sstime[512];
856:
857: fname = (char *)malloc(1024*sizeof(char));
858: strcpy(fname,getenv("HOME"));
859: strcat(fname,"/.ox.");
860: tt = time(NULL);
861: sprintf(sstime,"%ld",(long) tt);
862: strcat(fname,sstime);
863: if (fname[strlen(fname)-1] == '\n') {
864: fname[strlen(fname)-1] = '\0';
865: }
866: /* fprintf(stderr,"OxPortFileName=%s\n",fname); */
867: OxPortFileName = fname;
868: return(fname);
869: }
870: int oxRemovePortFile(void) {
871: char fname[1024];
872: FILE *fp;
1.5 takayama 873: SET_MYERROROUT;
1.1 maekawa 874: strcpy(fname,OxPortFileName);
875: strcat(fname,".control");
876: if ((fp=fopen(fname,"r")) == NULL) {
877: }{
878: fclose(fp);
879: if (unlink(fname)) {
880: fprintf(MyErrorOut,"fail unlink.\n");
881: }
882:
883: }
884: strcpy(fname,OxPortFileName);
885: strcat(fname,".data");
886: if ((fp=fopen(fname,"r")) == NULL) {
887: }{
888: fclose(fp);
889: if (unlink(fname)) {
890: fprintf(MyErrorOut,"fail unlink.\n");
891: }
892: }
893: }
894:
895: char *oxGenPass(void) {
1.3 takayama 896: static int seed = 0;
1.1 maekawa 897: long p;
898: char *s;
1.21 takayama 899: int i,n;
1.3 takayama 900: if (seed == 0) {
901: seed = (int) time(NULL) + (int) &p;
902: srandom((unsigned int) seed);
903: }
1.21 takayama 904: s = (char *)malloc(128*sizeof(char));
905: if (s == NULL) { fprintf(stderr,"No more memory.\n"); return(s); }
906: n = (((int) s) + (int) time(NULL)) % 100;
907: for (i=0; i < n ; i++) random();
1.1 maekawa 908: p = random();
909: sprintf(s,"%ld",p);
910: return(s);
911: }
912:
913:
914: static void cancelConnection() {
1.12 takayama 915: #if defined(__CYGWIN__)
916: extern sigjmp_buf MyEnv_oxmisc;
917: #else
1.1 maekawa 918: extern jmp_buf MyEnv_oxmisc;
1.12 takayama 919: #endif
1.1 maekawa 920: signal(SIGALRM,SIG_IGN);
921: fprintf(stderr,"Time out in TCP/IP connection.\n");
1.12 takayama 922: #if defined(__CYGWIN__)
923: siglongjmp(MyEnv_oxmisc,1);
924: #else
1.1 maekawa 925: longjmp(MyEnv_oxmisc,1);
1.12 takayama 926: #endif
1.1 maekawa 927: }
928:
929: oxclientp oxCreateClient2(int fdstream,int portStream,
1.22 takayama 930: int fdcontrol,int portControl,int ipmask,
931: char *passControl, char *passData)
1.1 maekawa 932: {
933: int v = 0;
934: int fdControl = -1;
935: int fdStream = -1;
936: int m;
937:
938: char *s;
939: oxclientp client;
1.12 takayama 940: #if defined(__CYGWIN__)
941: extern sigjmp_buf MyEnv_oxmisc;
942: #else
943: extern jmp_buf MyEnv_oxmisc;
944: #endif
1.1 maekawa 945: int controlByteOrder, engineByteOrder;
946:
947: v = !Quiet;
1.12 takayama 948: #if defined(__CYGWIN__)
949: if (sigsetjmp(MyEnv_oxmisc,1)) {
950: #else
1.1 maekawa 951: if (setjmp(MyEnv_oxmisc)) {
1.12 takayama 952: #endif
1.1 maekawa 953: return(NULL);
954: }else{
955: }
1.11 takayama 956: alarm((unsigned int) 20); /* setup timeout. */
1.1 maekawa 957: signal(SIGALRM,cancelConnection);
958:
959: switch(ipmask) {
960: case 0:/* only local */
961: fdControl = socketAcceptLocal(fdcontrol);
962: fdStream = socketAcceptLocal(fdstream);
963: break;
964: default:/* any */
965: fdControl = socketAccept(fdcontrol);
966: fdStream = socketAccept(fdstream);
967: break;
968: }
969: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
970: if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
971:
972: if (fdStream == -1 || fdControl == -1) {
1.16 takayama 973: fprintf(stderr,"\nOpen error in oxCreateClient2.\n");
974: fprintf(stderr,"fdStream=%d, fdControl=%d\n",fdStream,fdControl);
1.1 maekawa 975: return(NULL);
976: }
977:
1.6 takayama 978: /* Authentication by password. */
1.22 takayama 979: m = strlen(passControl)+strlen(passData);
1.10 takayama 980: if (m > 0) {
981: s = (char *)mymalloc(sizeof(char)*(m+1));
1.22 takayama 982: m = strlen(passControl); s[0] = 0;
1.10 takayama 983: read(fdControl,s,m+1); s[m] = '\0';
1.22 takayama 984: if (strcmp(s,passControl) != 0) {
985: fprintf(stderr,"s=%s, passControl=%s\n",s,passControl);
1.10 takayama 986: fprintf(stderr,"oxCreateClient2(): password authentication failed for control channel.\n");
987: close(fdControl);
988: return(NULL);
989: }
1.22 takayama 990: m = strlen(passData); s[0] = 0;
1.10 takayama 991: read(fdStream,s,m+1); s[m] = '\0';
1.22 takayama 992: if (strcmp(s,passData) != 0) {
993: fprintf(stderr,"s=%s, passData=%s\n",s,passData);
1.10 takayama 994: fprintf(stderr,"oxCreateClient2(): password authentication failed for data channel.\n");
995: close(fdStream);
996: return(NULL);
997: }
1.1 maekawa 998: }
999: signal(SIGALRM,SIG_IGN);
1000:
1001: controlByteOrder = oxSetByteOrder(fdControl);
1002: if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9 takayama 1003: (controlByteOrder == 0? "network byte order":
1004: (controlByteOrder == 1? "little indican":
1005: "big indian")));
1.1 maekawa 1006: engineByteOrder = oxSetByteOrder(fdStream);
1007: if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9 takayama 1008: (engineByteOrder == 0? "network byte order":
1009: (engineByteOrder == 1? "little indican":
1010: "big indian")));
1.1 maekawa 1011:
1012:
1013: client = (oxclientp) mymalloc(sizeof(oxclient));
1014: oxInitClient(client);
1015: client->datafp2 = fp2open(fdStream);
1016: if (client->datafp2 == NULL) {
1017: fprintf(stderr,"oxCreateClient2(): fp2open(fd) failed.\n");
1018: return(NULL);
1019: }
1020: client->dataport = portStream;
1021: client->controlport = portControl;
1022: client->controlfd = fdControl;
1.13 takayama 1023: client->id = oxGetClientID();
1.1 maekawa 1024: client->type = CLIENT_SOCKET; /* socket */
1025: client->engineByteOrder = engineByteOrder;
1026: client->controlByteOrder = controlByteOrder;
1027: return(client);
1028: }
1029:
1030: int oxSetByteOrder(int fd) {
1031: char data[1];
1032: int peertype;
1033: /* It is for client. read and next write. */
1034: /* oxSocketSelect0(fd,10); wait. */
1035: read(fd,data,1);
1036: peertype = (unsigned char) data[0];
1037:
1038: /* We support only Network byte order */
1039: data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
1040: write(fd,data,1);
1041:
1042: return(OX_BYTE_NETWORK_BYTE_ORDER);
1043: }
1044:
1.17 takayama 1045: int oxTellMyByteOrder(int fdOut, int fdIn) {
1.1 maekawa 1046: char data[1];
1047: int peertype;
1048: /* It is for server. read and next write. */
1049:
1050: /* We support only Network byte order */
1051: data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
1.17 takayama 1052: write(fdOut,data,1);
1053: fsync(fdOut); /* returns 0 if normal. Does it work for socket? */
1.1 maekawa 1054:
1.17 takayama 1055: read(fdIn,data,1); /* Read pear's byte order */
1.1 maekawa 1056:
1057: return(OX_BYTE_NETWORK_BYTE_ORDER);
1058: }
1059:
1060:
1.14 takayama 1061: struct object OxClientList[MAX_N_OF_CLIENT];
1062: int OxClientListn = 0;
1063:
1064: int oxGetClientID() {
1065: extern struct object OxClientList[];
1066: extern int OxClientListn;
1067: extern struct object Nobj;
1068: int i;
1069: for (i=0; i<OxClientListn; i++) {
1070: if ((OxClientList[i]).tag == Snull) {
1071: return i;
1072: }
1073: }
1074: i = OxClientListn;
1075: (OxClientList[i]).tag = Snull;
1076: if (OxClientListn < MAX_N_OF_CLIENT-1) {
1077: OxClientListn++;
1078: return i;
1079: }else{
1080: fprintf(MyErrorOut,"oxGetClientID(): the client table is full. Returns ID = 0.\n");
1081: return 0;
1082: }
1083: }
1.1 maekawa 1084:
1.18 takayama 1085: char *oxFIDtoStr(int id) {
1086: switch( id ) {
1087: case SM_mathcap:
1088: return "SM_mathcap"; break;
1089: case SM_setMathCap:
1090: return "SM_setMathCap"; break;
1091: case SM_pops:
1092: return "SM_pops"; break;
1093: case SM_getsp:
1094: return "SM_getsp"; break;
1095: case SM_dupErrors:
1096: return "SM_dupErrors"; break;
1097: case SM_pushCMOtag:
1098: return "SM_pushCMOtag"; break;
1099: case SM_setName:
1100: return "SM_setName"; break;
1101: case SM_evalName:
1102: return "SM_evalName"; break;
1103: case SM_executeStringByLocalParser:
1104: return "SM_executeStringByLocalParser"; break;
1105: case SM_executeFunction:
1106: return "SM_executeFunction"; break;
1.20 takayama 1107: case SM_executeFunctionWithOptionalArgument:
1108: return "SM_executeFunctionWithOptionalArgument"; break;
1.18 takayama 1109: case SM_popCMO:
1110: return "SM_popCMO"; break;
1111: case SM_popString:
1112: return "SM_popString"; break;
1113: case SM_shutdown:
1114: return "SM_shutdown"; break;
1115: case SM_beginBlock:
1116: return "SM_beginBlock"; break;
1117: case SM_endBlock:
1118: return "SM_endBlock"; break;
1119: default:
1120: return "Unknown to oxFIDtoStr"; break;
1121: }
1122: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>