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