Annotation of OpenXM/src/ox_toolkit/oxf.c, Revision 1.7
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.7 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.6 2000/11/28 04:24:12 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.7 ! ohara 87: oxfp->serial_number = 0;
1.5 ohara 88: oxfp->control = NULL;
89: oxfp->error = 0;
90: oxfp->mathcap = NULL;
1.1 ohara 91: return oxfp;
92: /* oxfp->fp = fdopen(fd, "a+"); */
93: /* return (oxfp->fp != NULL)? oxfp: NULL; */
1.7 ! ohara 94: }
! 95:
! 96: int oxf_fileno(OXFILE *oxfp)
! 97: {
! 98: return oxfp->fd;
1.1 ohara 99: }
100:
101: OXFILE *oxf_control(OXFILE *oxfp)
102: {
1.5 ohara 103: return oxfp->control;
1.1 ohara 104: }
105:
106: /* The function determines a byte order of integer on the OpenXM
107: connection `oxfp'. */
108: /* REMARKS:
109: we request the byte order of macine integer on a local machine by
110: (*(char *)&offer). The fact depends on OX_BYTE_LITTLE_ENDIAN==1. */
111: void oxf_determine_byteorder_client(OXFILE *oxfp)
112: {
113: int offer = OX_BYTE_LITTLE_ENDIAN;
114: char receiv;
115: int mode;
116:
117: oxf_read(&receiv, 1, 1, oxfp);
118: oxf_write(&offer, 1, 1, oxfp);
119: mode = (receiv == *(char *)&offer);
120: oxf_setopt(oxfp, mode);
121: }
122:
123: /* Server 側ではこちらを用いる */
124: /* いまの実装は dup されていることが前提になっている */
125: void oxf_determine_byteorder_server(OXFILE *oxfp)
126: {
127: int offer = OX_BYTE_LITTLE_ENDIAN;
128: char receiv;
129: int mode;
130:
131: oxf_write(&offer, 1, 1, oxfp);
132: oxf_read(&receiv, 1, 1, oxfp);
133: mode = (receiv == *(char *)&offer);
134: oxf_setopt(oxfp, mode);
135: }
136:
137: void oxf_flush(OXFILE *oxfp)
138: {
139: /* fflush(oxfp->fp); */
140: }
141:
142: void oxf_close(OXFILE *oxfp)
143: {
144: close(oxfp->fd);
145: /* fclose(oxfp->fp); */
146: }
147:
148: #define OXF_SETOPT_NBO 0
149: #define OXF_SETOPT_LBO 1
150:
151: void oxf_setopt(OXFILE *oxfp, int mode)
152: {
153: if (mode == OXF_SETOPT_LBO) {
154: oxfp->send_int32 = send_int32_lbo;
155: oxfp->receive_int32 = receive_int32_lbo;
156: }else if (mode == OXF_SETOPT_NBO) {
157: oxfp->send_int32 = send_int32_nbo;
158: oxfp->receive_int32 = receive_int32_nbo;
159: }
160: }
161:
1.4 ohara 162: int oxf_listen(short *portp)
163: {
164: char localhost[MAXHOSTNAMELEN];
165: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
1.5 ohara 166: return mysocketListen(localhost, portp);
167: }
168: return -1;
1.4 ohara 169: }
170:
1.1 ohara 171: OXFILE *oxf_connect_active(char *hostname, short port)
172: {
173: int fd = mysocketOpen(hostname, port);
174: return oxf_open(fd);
175: }
176:
177: OXFILE *oxf_connect_passive(int listened)
178: {
179: int fd = mysocketAccept(listened);
180: return oxf_open(fd);
181: }
182:
183: #define LENGTH_OF_ONETIME_PASSWORD 64
184:
185: /* a password generator. */
186: char *generate_otp()
187: {
1.5 ohara 188: static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1.1 ohara 189: static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};
190: int i;
191:
192: srandom(time(NULL));
193: for(i=0; i<LENGTH_OF_ONETIME_PASSWORD; i++) {
194: otp[i] = crypto[random() % (sizeof(crypto)-1)];
195: }
196: return otp;
197: }
198:
199: /* proceeding a one time password. */
200: /* if the password is right,
201: then the function returns 1, if otherwise, then 0. */
202: int oxf_confirm_client(OXFILE *oxfp, char *passwd)
203: {
204: int len = strlen(passwd)+1;
205: char *buf = alloca(len);
206:
207: oxf_read(buf, 1, len, oxfp);
208: return !strcmp(passwd, buf);
209: }
210:
211: int oxf_confirm_server(OXFILE *oxfp, char *passwd)
212: {
213: return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);
214: }
215:
1.6 ohara 216: __inline__
217: static mathcap *oxf_mathcap(OXFILE *oxfp)
1.5 ohara 218: {
219: if (oxfp->mathcap == NULL) {
220: oxfp->mathcap = new_mathcap();
221: }
1.6 ohara 222: return oxfp->mathcap;
223: }
224:
225: cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp)
226: {
227: return mathcap_get(oxf_mathcap(oxfp));
228: }
229:
230: void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob)
231: {
232: mathcap_update(oxf_mathcap(oxfp), ob);
1.5 ohara 233: }
234:
1.1 ohara 235: /* example: which("xterm", getenv("PATH")); */
236: char *which(char *exe, const char *env)
237: {
238: char *tok;
239: char *path;
240: char delim[] = ":";
241: char *e = alloca(strlen(env)+1);
242: strcpy(e, env);
243: tok = strtok(e, delim);
244: while (tok != NULL) {
245: path = malloc(strlen(tok)+strlen(exe)+2);
246: sprintf(path, "%s/%s", tok, exe);
247: if (access(path, X_OK&R_OK) == 0) {
248: return path;
249: }
250: free(path);
251: tok = strtok(NULL, delim);
252: }
253: return NULL;
254: }
255:
256: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
257: int oxc_start(char *remote_host, short port, char *passwd)
258: {
259: char localhost[MAXHOSTNAMELEN];
260: char ports[128];
261: int pid = 0;
1.2 ohara 262: char *cmd = "oxc";
1.1 ohara 263:
264: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
265: if ((pid = fork()) == 0) {
266: sprintf(ports, "%d", port);
267: #ifdef DEBUG
268: fprintf(stderr, "oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
269: #endif
270: execlp("ssh", remote_host, "-f", cmd,
271: "-h", localhost, "-p", ports,"-c", passwd, NULL);
272: }
273: }
274: return pid;
1.4 ohara 275: }
276:
277: /* Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
278: OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
279: {
1.5 ohara 280: short port = 0;
281: int listened;
1.4 ohara 282:
1.5 ohara 283: if ((listened = oxf_listen(&port)) != -1) {
284: send_ox_cmo(oxfp, (cmo *)new_cmo_int32(port));
285: send_ox_cmo(oxfp, (cmo *)new_cmo_string(cmd));
286: send_ox_cmo(oxfp, (cmo *)new_cmo_int32(2)); /* number of arguments */
287: send_ox_cmo(oxfp, (cmo *)new_cmo_string("oxc_open"));
288: send_ox_command(oxfp, SM_executeFunction);
289: return oxf_connect_passive(listened);
290: }
291: return NULL;
1.1 ohara 292: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>