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