Annotation of OpenXM/src/ox_toolkit/oxf.c, Revision 1.6
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.6 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.5 2000/11/24 05:49:27 ohara Exp $ */
1.1 ohara 3:
4: /*
5: This module includes functions for sending/receiveng CMO's.
6: Some commnets is written in Japanese by the EUC-JP coded
7: character set.
8: */
9:
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <unistd.h>
14: #include <fcntl.h>
15: #include <sys/file.h>
16: #include <sys/param.h>
17: #include <time.h>
18:
19: #include "mysocket.h"
20: #include "ox_toolkit.h"
21:
1.6 ! ohara 22: static mathcap *oxf_mathcap(OXFILE *oxfp);
! 23:
1.4 ohara 24: static int send_int32_lbo(OXFILE *oxfp, int int32);
25: static int send_int32_nbo(OXFILE *oxfp, int int32);
26: static int receive_int32_lbo(OXFILE *oxfp);
27: static int receive_int32_nbo(OXFILE *oxfp);
28:
1.2 ohara 29: int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp)
30: {
1.5 ohara 31: int n = read(oxfp->fd, buffer, size*num);
32: if (n <= 0) {
33: oxfp->error = 1;
34: }
1.2 ohara 35: return n;
36: }
37:
38: int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp)
39: {
40: return write(oxfp->fd, buffer, size*num);
41: }
42:
1.4 ohara 43: /* sending an object of int32 type with Network Byte Order.
44: (not equal to cmo_int32 type) */
45: static int send_int32_nbo(OXFILE *oxfp, int int32)
46: {
47: int32 = htonl(int32);
48: return oxf_write(&int32, sizeof(int), 1, oxfp);
49: }
50:
51: /* sending an object of int32 type with Local Byte Order.
52: (not equal to cmo_int32 type) */
53: static int send_int32_lbo(OXFILE *oxfp, int int32)
54: {
55: return oxf_write(&int32, sizeof(int), 1, oxfp);
56: }
57:
58: /* receiving an object of int32 type with Network Byte Order.
59: (not equal to cmo_int32 type) */
60: static int receive_int32_nbo(OXFILE *oxfp)
61: {
62: int tag;
63: oxf_read(&tag, sizeof(int), 1, oxfp);
64: return ntohl(tag);
65: }
66:
67: /* receiving an object of int32 type with Local Byte Order.
68: (not equal to cmo_int32 type) */
69: static int receive_int32_lbo(OXFILE *oxfp)
70: {
71: int tag;
72: oxf_read(&tag, sizeof(int), 1, oxfp);
73: return tag;
74: }
75:
76: /* socket システムコールなどで socket を開いたのち、
77: fdopen(sd, "a+") でバッファリングする(予定)。("w+" ではない)
78: バッファリングの後、バイトオーダを決定し、
79: oxf_setopt() で関数ポインタを設定し直す。*/
80:
1.1 ohara 81: OXFILE *oxf_open(int fd)
82: {
83: OXFILE *oxfp = (OXFILE *)malloc(sizeof(OXFILE));
84: oxfp->fd = fd;
85: oxfp->send_int32 = send_int32_nbo;
86: oxfp->receive_int32 = receive_int32_nbo;
1.5 ohara 87: oxfp->control = NULL;
88: oxfp->error = 0;
89: oxfp->mathcap = NULL;
1.1 ohara 90: return oxfp;
91: /* oxfp->fp = fdopen(fd, "a+"); */
92: /* return (oxfp->fp != NULL)? oxfp: NULL; */
93: }
94:
95: OXFILE *oxf_control(OXFILE *oxfp)
96: {
1.5 ohara 97: return oxfp->control;
1.1 ohara 98: }
99:
100: /* The function determines a byte order of integer on the OpenXM
101: connection `oxfp'. */
102: /* REMARKS:
103: we request the byte order of macine integer on a local machine by
104: (*(char *)&offer). The fact depends on OX_BYTE_LITTLE_ENDIAN==1. */
105: void oxf_determine_byteorder_client(OXFILE *oxfp)
106: {
107: int offer = OX_BYTE_LITTLE_ENDIAN;
108: char receiv;
109: int mode;
110:
111: oxf_read(&receiv, 1, 1, oxfp);
112: oxf_write(&offer, 1, 1, oxfp);
113: mode = (receiv == *(char *)&offer);
114: oxf_setopt(oxfp, mode);
115: }
116:
117: /* Server 側ではこちらを用いる */
118: /* いまの実装は dup されていることが前提になっている */
119: void oxf_determine_byteorder_server(OXFILE *oxfp)
120: {
121: int offer = OX_BYTE_LITTLE_ENDIAN;
122: char receiv;
123: int mode;
124:
125: oxf_write(&offer, 1, 1, oxfp);
126: oxf_read(&receiv, 1, 1, oxfp);
127: mode = (receiv == *(char *)&offer);
128: oxf_setopt(oxfp, mode);
129: }
130:
131: void oxf_flush(OXFILE *oxfp)
132: {
133: /* fflush(oxfp->fp); */
134: }
135:
136: void oxf_close(OXFILE *oxfp)
137: {
138: close(oxfp->fd);
139: /* fclose(oxfp->fp); */
140: }
141:
142: #define OXF_SETOPT_NBO 0
143: #define OXF_SETOPT_LBO 1
144:
145: void oxf_setopt(OXFILE *oxfp, int mode)
146: {
147: if (mode == OXF_SETOPT_LBO) {
148: oxfp->send_int32 = send_int32_lbo;
149: oxfp->receive_int32 = receive_int32_lbo;
150: }else if (mode == OXF_SETOPT_NBO) {
151: oxfp->send_int32 = send_int32_nbo;
152: oxfp->receive_int32 = receive_int32_nbo;
153: }
154: }
155:
1.4 ohara 156: int oxf_listen(short *portp)
157: {
158: char localhost[MAXHOSTNAMELEN];
159: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
1.5 ohara 160: return mysocketListen(localhost, portp);
161: }
162: return -1;
1.4 ohara 163: }
164:
1.1 ohara 165: OXFILE *oxf_connect_active(char *hostname, short port)
166: {
167: int fd = mysocketOpen(hostname, port);
168: return oxf_open(fd);
169: }
170:
171: OXFILE *oxf_connect_passive(int listened)
172: {
173: int fd = mysocketAccept(listened);
174: return oxf_open(fd);
175: }
176:
177: #define LENGTH_OF_ONETIME_PASSWORD 64
178:
179: /* a password generator. */
180: char *generate_otp()
181: {
1.5 ohara 182: static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1.1 ohara 183: static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};
184: int i;
185:
186: srandom(time(NULL));
187: for(i=0; i<LENGTH_OF_ONETIME_PASSWORD; i++) {
188: otp[i] = crypto[random() % (sizeof(crypto)-1)];
189: }
190: return otp;
191: }
192:
193: /* proceeding a one time password. */
194: /* if the password is right,
195: then the function returns 1, if otherwise, then 0. */
196: int oxf_confirm_client(OXFILE *oxfp, char *passwd)
197: {
198: int len = strlen(passwd)+1;
199: char *buf = alloca(len);
200:
201: oxf_read(buf, 1, len, oxfp);
202: return !strcmp(passwd, buf);
203: }
204:
205: int oxf_confirm_server(OXFILE *oxfp, char *passwd)
206: {
207: return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);
208: }
209:
1.6 ! ohara 210: __inline__
! 211: static mathcap *oxf_mathcap(OXFILE *oxfp)
1.5 ohara 212: {
213: if (oxfp->mathcap == NULL) {
214: oxfp->mathcap = new_mathcap();
215: }
1.6 ! ohara 216: return oxfp->mathcap;
! 217: }
! 218:
! 219: cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp)
! 220: {
! 221: return mathcap_get(oxf_mathcap(oxfp));
! 222: }
! 223:
! 224: void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob)
! 225: {
! 226: mathcap_update(oxf_mathcap(oxfp), ob);
1.5 ohara 227: }
228:
1.1 ohara 229: /* example: which("xterm", getenv("PATH")); */
230: char *which(char *exe, const char *env)
231: {
232: char *tok;
233: char *path;
234: char delim[] = ":";
235: char *e = alloca(strlen(env)+1);
236: strcpy(e, env);
237: tok = strtok(e, delim);
238: while (tok != NULL) {
239: path = malloc(strlen(tok)+strlen(exe)+2);
240: sprintf(path, "%s/%s", tok, exe);
241: if (access(path, X_OK&R_OK) == 0) {
242: return path;
243: }
244: free(path);
245: tok = strtok(NULL, delim);
246: }
247: return NULL;
248: }
249:
250: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
251: int oxc_start(char *remote_host, short port, char *passwd)
252: {
253: char localhost[MAXHOSTNAMELEN];
254: char ports[128];
255: int pid = 0;
1.2 ohara 256: char *cmd = "oxc";
1.1 ohara 257:
258: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
259: if ((pid = fork()) == 0) {
260: sprintf(ports, "%d", port);
261: #ifdef DEBUG
262: fprintf(stderr, "oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
263: #endif
264: execlp("ssh", remote_host, "-f", cmd,
265: "-h", localhost, "-p", ports,"-c", passwd, NULL);
266: }
267: }
268: return pid;
1.4 ohara 269: }
270:
271: /* Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
272: OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
273: {
1.5 ohara 274: short port = 0;
275: int listened;
1.4 ohara 276:
1.5 ohara 277: if ((listened = oxf_listen(&port)) != -1) {
278: send_ox_cmo(oxfp, (cmo *)new_cmo_int32(port));
279: send_ox_cmo(oxfp, (cmo *)new_cmo_string(cmd));
280: send_ox_cmo(oxfp, (cmo *)new_cmo_int32(2)); /* number of arguments */
281: send_ox_cmo(oxfp, (cmo *)new_cmo_string("oxc_open"));
282: send_ox_command(oxfp, SM_executeFunction);
283: return oxf_connect_passive(listened);
284: }
285: return NULL;
1.1 ohara 286: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>