Annotation of OpenXM/src/kan96xx/plugin/oxmisc.c, Revision 1.10
1.10 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc.c,v 1.9 2001/05/04 01:06:30 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: static int clnum = 0;
615: int v = 0;
616: int fdControl = -1;
617: int fdStream = -1;
618: oxclientp client;
619: int controlByteOrder, engineByteOrder;
620: v = !Quiet;
621: if (portControl != -1) {
622: fdControl = socketConnect(sname,portControl);
623: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
624: }
625: if (portStream != -1) {
626: sleep(1); /* wait */
627: fdStream = socketConnect(sname,portStream);
628: if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
629: }
630:
631: if (fdStream == -1 || fdControl == -1) {
632: fprintf(stderr,"\nOpen error in oxCreateClient.\n");
633: return(NULL);
634: }
635:
636: controlByteOrder = oxSetByteOrder(fdControl);
637: if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9 takayama 638: (controlByteOrder == 0? "network byte order":
639: (controlByteOrder == 1? "little indican":
640: "big indian")));
1.1 maekawa 641: engineByteOrder = oxSetByteOrder(fdStream);
642: if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9 takayama 643: (engineByteOrder == 0? "network byte order":
644: (engineByteOrder == 1? "little indican":
645: "big indian")));
1.1 maekawa 646:
647: client = (oxclientp) mymalloc(sizeof(oxclient));
648: oxInitClient(client);
649: client->datafp2 = fp2open(fdStream);
650: if (client->datafp2 == NULL) {
651: fprintf(stderr,"oxCreateClient(): fp2open(fd) failed.\n");
652: return(NULL);
653: }
654: client->dataport = portStream;
655: client->controlport = portControl;
656: client->controlfd = fdControl;
657: client->id = clnum; clnum++;
658: client->type = CLIENT_SOCKET; /* socket */
659: client->engineByteOrder = engineByteOrder;
660: client->controlByteOrder = controlByteOrder;
661: return(client);
662: }
663:
664: oxclientp oxCreateClientFile(char *fname,char *mode,char *controlName,char *cmode)
665: {
666: static int clnum = 0x8000;
667: int v = 0;
668: int fdControl = -1;
669: int fdStream = -1;
670: oxclientp client;
671: v = 1;
672: if (strcmp(mode,"w") == 0) {
673: fdStream = creat(fname,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
674: if (fdStream < 0) {
675: fprintf(stderr,"\nCreat failed for %s\n",fname); return(NULL);
676: }
677: }else if (strcmp(mode,"r")==0) {
678: fdStream = open(fname,O_RDONLY);
679: if (fdStream < 0) {
680: fprintf(stderr,"\nOpen failed for %s\n",fname); return(NULL);
681: }
682: }else {
683: fprintf(stderr,"\nThe mode %s is not supported.\n",mode); return(NULL);
684: }
685:
686: if (strcmp(cmode,"w") == 0) {
687: fdControl = creat(controlName,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
688: if (fdControl < 0) {
689: fprintf(stderr,"\nCreat failed for %s\n",controlName); return(NULL);
690: }
691: }else if (strcmp(cmode,"r")==0) {
692: fdControl = open(controlName,O_RDONLY);
693: if (fdControl < 0) {
694: fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
695: }
696: }else if (strcmp(cmode,"rw")==0) {
697: fdControl = open(controlName,O_RDWR);
698: if (fdControl < 0) {
699: fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
700: }
701: }else {
702: fprintf(stderr,"\nThe mode %s is not supported.\n",cmode); return(NULL);
703: }
704:
705:
706: client = (oxclientp) mymalloc(sizeof(oxclient));
707: oxInitClient(client);
708: client->datafp2 = fp2open(fdStream);
709: if (client->datafp2 == NULL) {
710: fprintf(stderr,"oxCreateClientFile(): fp2open(fd) failed.\n");
711: return(NULL);
712: }
713: client->dataport = 0;
714: client->controlport = 0;
715: client->controlfd = fdControl;
716: client->id = clnum; clnum++;
717: client->type = CLIENT_FILE;
718: client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
719: client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
720: return(client);
721: }
722:
723: void oxSendOXheader_generic(int type,int fd,ox_stream ox,
1.9 takayama 724: int k,int serial)
1.1 maekawa 725: {
726: static int ss = 0;
727: extern int UseOXPacketSerial;
728: if (serial >= 0) ss = serial;
729: else ss++;
730: if (ss < 0) ss=0;
731: if (type == 0) { /* fd */
732: oxfdSendInt32(fd,k);
733: if (UseOXPacketSerial) oxfdSendInt32(fd,ss);
734: }else {
735: oxSendInt32(ox,k);
736: if (UseOXPacketSerial) oxSendInt32(ox,ss);
737: }
738: }
739: void oxSendOXheader(ox_stream ostream,int k,int serial) {
740: oxSendOXheader_generic(1,-1,ostream,k,serial);
741: }
742: void oxfdSendOXheader(int fd,int k,int serial) {
743: oxSendOXheader_generic(0,fd,(ox_stream) NULL,k,serial);
744: }
745:
746: int oxfdGetOXheader(int fd,int *sss)
747: {
748: char d[4];
749: int i;
750: int m;
751:
752: for (i=0; i<4; i++) {
753: d[i] = readOneByte(fd);
754: }
755: m = ntohl(* ( (int *)d));
756: *sss = -1;
757: if (UseOXPacketSerial) {
758: for (i=0; i<4; i++) {
759: d[i] = readOneByte(fd);
760: }
761: *sss = ntohl(* ( (int *)d));
762: }
763: return(m);
764: }
765:
766: int oxGetOXheader(ox_stream ostream,int *sss)
767: {
768: char d[4];
769: int m;
770: int i;
771:
772: unlockCtrlCForOx(); /* temporary unlock */
773: while (fp2select(ostream,1000) == 0) ;
774: restoreLockCtrlCForOx();
775:
776: for (i=0; i<4; i++) {
777: d[i] = fp2fgetc(ostream);
778: }
779: m = ntohl(* ( (int *)d));
780: *sss = -1;
781: if (UseOXPacketSerial) {
782: for (i=0; i<4; i++) {
783: d[i] = fp2fgetc(ostream);
784: }
785: *sss = ntohl(* ( (int *)d));
786: }
787: return(m);
788: }
789:
790:
791: oxWritePortFile(int func,int port,char *fname) {
792: char name[1024];
793: FILE *fp;
794: strcpy(name,fname);
795: if (func == 0) {
796: strcat(name,".control");
797: fp = fopen(name,"w");
798: fprintf(fp,"%05d\n",port);
799: fclose(fp);
800: }else {
801: strcat(name,".data");
802: fp = fopen(name,"w");
803: fprintf(fp,"%05d\n",port);
804: fclose(fp);
805: }
806: }
807: oxReadPortFile(int func,char *fname) {
808: int port = 0;
809: char name[1024];
810: FILE *fp;
811: strcpy(name,fname);
812: if (func == 0) {
813: strcat(name,".control");
814: fp = fopen(name,"r");
815: fscanf(fp,"%d",&port);
816: fclose(fp);
817: }else {
818: strcat(name,".data");
819: fp = fopen(name,"r");
820: fscanf(fp,"%d",&port);
821: fclose(fp);
822: }
823: return(port);
824: }
825: char *oxGenPortFile(void) {
826: char *fname;
827: time_t tt;
828: char sstime[512];
829:
830: fname = (char *)malloc(1024*sizeof(char));
831: strcpy(fname,getenv("HOME"));
832: strcat(fname,"/.ox.");
833: tt = time(NULL);
834: sprintf(sstime,"%ld",(long) tt);
835: strcat(fname,sstime);
836: if (fname[strlen(fname)-1] == '\n') {
837: fname[strlen(fname)-1] = '\0';
838: }
839: /* fprintf(stderr,"OxPortFileName=%s\n",fname); */
840: OxPortFileName = fname;
841: return(fname);
842: }
843: int oxRemovePortFile(void) {
844: char fname[1024];
845: FILE *fp;
1.5 takayama 846: SET_MYERROROUT;
1.1 maekawa 847: strcpy(fname,OxPortFileName);
848: strcat(fname,".control");
849: if ((fp=fopen(fname,"r")) == NULL) {
850: }{
851: fclose(fp);
852: if (unlink(fname)) {
853: fprintf(MyErrorOut,"fail unlink.\n");
854: }
855:
856: }
857: strcpy(fname,OxPortFileName);
858: strcat(fname,".data");
859: if ((fp=fopen(fname,"r")) == NULL) {
860: }{
861: fclose(fp);
862: if (unlink(fname)) {
863: fprintf(MyErrorOut,"fail unlink.\n");
864: }
865: }
866: }
867:
868: char *oxGenPass(void) {
1.3 takayama 869: static int seed = 0;
1.1 maekawa 870: long p;
871: char *s;
1.3 takayama 872: int i;
873: if (seed == 0) {
874: seed = (int) time(NULL) + (int) &p;
875: srandom((unsigned int) seed);
876: }
877: for (i=0; i < ((int) &p) % 100 ; i++) random();
1.1 maekawa 878: p = random();
879: s = (char *)malloc(128*sizeof(char));
880: sprintf(s,"%ld",p);
881: return(s);
882: }
883:
884:
885: static void cancelConnection() {
886: extern jmp_buf MyEnv_oxmisc;
887: signal(SIGALRM,SIG_IGN);
888: fprintf(stderr,"Time out in TCP/IP connection.\n");
889: longjmp(MyEnv_oxmisc,1);
890: }
891:
892: oxclientp oxCreateClient2(int fdstream,int portStream,
1.9 takayama 893: int fdcontrol,int portControl,int ipmask,char *pass)
1.1 maekawa 894: {
895: static int clnum = 0;
896: int v = 0;
897: int fdControl = -1;
898: int fdStream = -1;
899: int m;
900:
901: char *s;
902: oxclientp client;
903: extern jmp_buf MyEnv_oxmisc ;
904: int controlByteOrder, engineByteOrder;
905:
906: v = !Quiet;
907: if (setjmp(MyEnv_oxmisc)) {
908: return(NULL);
909: }else{
910: }
911: alarm((unsigned int) 10); /* setup timeout. */
912: signal(SIGALRM,cancelConnection);
913:
914: switch(ipmask) {
915: case 0:/* only local */
916: fdControl = socketAcceptLocal(fdcontrol);
917: fdStream = socketAcceptLocal(fdstream);
918: break;
919: default:/* any */
920: fdControl = socketAccept(fdcontrol);
921: fdStream = socketAccept(fdstream);
922: break;
923: }
924: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
925: if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
926:
927: if (fdStream == -1 || fdControl == -1) {
928: fprintf(stderr,"\nOpen error in oxCreateClient.\n");
929: return(NULL);
930: }
931:
1.6 takayama 932: /* Authentication by password. */
1.1 maekawa 933: m = strlen(pass);
1.10 ! takayama 934: if (m > 0) {
! 935: s = (char *)mymalloc(sizeof(char)*(m+1));
! 936: read(fdControl,s,m+1); s[m] = '\0';
! 937: if (strcmp(s,pass) != 0) {
! 938: fprintf(stderr,"oxCreateClient2(): password authentication failed for control channel.\n");
! 939: close(fdControl);
! 940: return(NULL);
! 941: }
! 942: read(fdStream,s,m+1); s[m] = '\0';
! 943: if (strcmp(s,pass) != 0) {
! 944: fprintf(stderr,"oxCreateClient2(): password authentication failed for data channel.\n");
! 945: close(fdStream);
! 946: return(NULL);
! 947: }
1.1 maekawa 948: }
949: signal(SIGALRM,SIG_IGN);
950:
951: controlByteOrder = oxSetByteOrder(fdControl);
952: if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9 takayama 953: (controlByteOrder == 0? "network byte order":
954: (controlByteOrder == 1? "little indican":
955: "big indian")));
1.1 maekawa 956: engineByteOrder = oxSetByteOrder(fdStream);
957: if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9 takayama 958: (engineByteOrder == 0? "network byte order":
959: (engineByteOrder == 1? "little indican":
960: "big indian")));
1.1 maekawa 961:
962:
963: client = (oxclientp) mymalloc(sizeof(oxclient));
964: oxInitClient(client);
965: client->datafp2 = fp2open(fdStream);
966: if (client->datafp2 == NULL) {
967: fprintf(stderr,"oxCreateClient2(): fp2open(fd) failed.\n");
968: return(NULL);
969: }
970: client->dataport = portStream;
971: client->controlport = portControl;
972: client->controlfd = fdControl;
973: client->id = clnum; clnum++;
974: client->type = CLIENT_SOCKET; /* socket */
975: client->engineByteOrder = engineByteOrder;
976: client->controlByteOrder = controlByteOrder;
977: return(client);
978: }
979:
980: int oxSetByteOrder(int fd) {
981: char data[1];
982: int peertype;
983: /* It is for client. read and next write. */
984: /* oxSocketSelect0(fd,10); wait. */
985: read(fd,data,1);
986: peertype = (unsigned char) data[0];
987:
988: /* We support only Network byte order */
989: data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
990: write(fd,data,1);
991:
992: return(OX_BYTE_NETWORK_BYTE_ORDER);
993: }
994:
995: int oxTellMyByteOrder(int fd) {
996: char data[1];
997: int peertype;
998: /* It is for server. read and next write. */
999:
1000: /* We support only Network byte order */
1001: data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
1002: write(fd,data,1);
1003: fsync(fd); /* returns 0 if normal. Does it work for socket? */
1004:
1005: read(fd,data,1);
1006:
1007: return(OX_BYTE_NETWORK_BYTE_ORDER);
1008: }
1009:
1010:
1011:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>