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