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