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