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