Annotation of OpenXM/src/ox_toolkit/oxf.c, Revision 1.12
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.12 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.11 2000/12/16 01:49:32 ohara Exp $ */
1.1 ohara 3:
4: /*
5: This module includes functions for sending/receiveng CMO's.
1.9 ohara 6: Some commnets are written in Japanese by the EUC-JP coded
1.1 ohara 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>
1.12 ! ohara 18:
! 19: #if defined(__sun__)
! 20: #include <netdb.h>
! 21: #include <sys/types.h>
! 22: #include <netinet/in.h>
! 23: #endif
1.1 ohara 24:
25: #include "mysocket.h"
26: #include "ox_toolkit.h"
27:
1.6 ohara 28: static mathcap *oxf_mathcap(OXFILE *oxfp);
29:
1.4 ohara 30: static int send_int32_lbo(OXFILE *oxfp, int int32);
31: static int send_int32_nbo(OXFILE *oxfp, int int32);
32: static int receive_int32_lbo(OXFILE *oxfp);
33: static int receive_int32_nbo(OXFILE *oxfp);
34:
1.2 ohara 35: int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp)
36: {
1.5 ohara 37: int n = read(oxfp->fd, buffer, size*num);
38: if (n <= 0) {
39: oxfp->error = 1;
40: }
1.2 ohara 41: return n;
42: }
43:
44: int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp)
45: {
46: return write(oxfp->fd, buffer, size*num);
47: }
48:
1.4 ohara 49: /* sending an object of int32 type with Network Byte Order.
50: (not equal to cmo_int32 type) */
51: static int send_int32_nbo(OXFILE *oxfp, int int32)
52: {
53: int32 = htonl(int32);
54: return oxf_write(&int32, sizeof(int), 1, oxfp);
55: }
56:
57: /* sending an object of int32 type with Local Byte Order.
58: (not equal to cmo_int32 type) */
59: static int send_int32_lbo(OXFILE *oxfp, int int32)
60: {
61: return oxf_write(&int32, sizeof(int), 1, oxfp);
62: }
63:
64: /* receiving an object of int32 type with Network Byte Order.
65: (not equal to cmo_int32 type) */
66: static int receive_int32_nbo(OXFILE *oxfp)
67: {
68: int tag;
69: oxf_read(&tag, sizeof(int), 1, oxfp);
70: return ntohl(tag);
71: }
72:
73: /* receiving an object of int32 type with Local Byte Order.
74: (not equal to cmo_int32 type) */
75: static int receive_int32_lbo(OXFILE *oxfp)
76: {
77: int tag;
78: oxf_read(&tag, sizeof(int), 1, oxfp);
79: return tag;
80: }
81:
1.9 ohara 82: /* (1) getting the fd by socket(2).
83: (2) preparing a buffer by fdopen(fd, "a+"). (not "w+")
84: (3) determing the byte order of the OX connection.
85: (4) setting function pointers by oxf_setopt().
86: */
1.1 ohara 87: OXFILE *oxf_open(int fd)
88: {
89: OXFILE *oxfp = (OXFILE *)malloc(sizeof(OXFILE));
1.11 ohara 90: oxfp = (OXFILE *)malloc(sizeof(OXFILE));
1.1 ohara 91: oxfp->fd = fd;
92: oxfp->send_int32 = send_int32_nbo;
93: oxfp->receive_int32 = receive_int32_nbo;
1.7 ohara 94: oxfp->serial_number = 0;
1.5 ohara 95: oxfp->control = NULL;
96: oxfp->error = 0;
97: oxfp->mathcap = NULL;
1.1 ohara 98: return oxfp;
99: /* oxfp->fp = fdopen(fd, "a+"); */
100: /* return (oxfp->fp != NULL)? oxfp: NULL; */
1.7 ohara 101: }
102:
103: int oxf_fileno(OXFILE *oxfp)
104: {
105: return oxfp->fd;
1.1 ohara 106: }
107:
108: OXFILE *oxf_control(OXFILE *oxfp)
109: {
1.5 ohara 110: return oxfp->control;
1.1 ohara 111: }
112:
113: /* The function determines a byte order of integer on the OpenXM
114: connection `oxfp'. */
115: /* REMARKS:
116: we request the byte order of macine integer on a local machine by
117: (*(char *)&offer). The fact depends on OX_BYTE_LITTLE_ENDIAN==1. */
118: void oxf_determine_byteorder_client(OXFILE *oxfp)
119: {
120: int offer = OX_BYTE_LITTLE_ENDIAN;
121: char receiv;
122: int mode;
123:
124: oxf_read(&receiv, 1, 1, oxfp);
125: oxf_write(&offer, 1, 1, oxfp);
126: mode = (receiv == *(char *)&offer);
127: oxf_setopt(oxfp, mode);
128: }
129:
1.9 ohara 130: /* If the program is an OX server, then you must use this function. */
1.1 ohara 131: void oxf_determine_byteorder_server(OXFILE *oxfp)
132: {
133: int offer = OX_BYTE_LITTLE_ENDIAN;
134: char receiv;
135: int mode;
136:
137: oxf_write(&offer, 1, 1, oxfp);
138: oxf_read(&receiv, 1, 1, oxfp);
139: mode = (receiv == *(char *)&offer);
140: oxf_setopt(oxfp, mode);
141: }
142:
143: void oxf_flush(OXFILE *oxfp)
144: {
145: /* fflush(oxfp->fp); */
146: }
147:
148: void oxf_close(OXFILE *oxfp)
149: {
150: close(oxfp->fd);
151: /* fclose(oxfp->fp); */
152: }
153:
154: #define OXF_SETOPT_NBO 0
155: #define OXF_SETOPT_LBO 1
156:
157: void oxf_setopt(OXFILE *oxfp, int mode)
158: {
159: if (mode == OXF_SETOPT_LBO) {
160: oxfp->send_int32 = send_int32_lbo;
161: oxfp->receive_int32 = receive_int32_lbo;
162: }else if (mode == OXF_SETOPT_NBO) {
163: oxfp->send_int32 = send_int32_nbo;
164: oxfp->receive_int32 = receive_int32_nbo;
165: }
166: }
167:
1.4 ohara 168: int oxf_listen(short *portp)
169: {
170: char localhost[MAXHOSTNAMELEN];
171: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
1.5 ohara 172: return mysocketListen(localhost, portp);
173: }
174: return -1;
1.4 ohara 175: }
176:
1.1 ohara 177: OXFILE *oxf_connect_active(char *hostname, short port)
178: {
179: int fd = mysocketOpen(hostname, port);
1.11 ohara 180: return (fd < 0)? NULL: oxf_open(fd);
1.1 ohara 181: }
182:
183: OXFILE *oxf_connect_passive(int listened)
184: {
185: int fd = mysocketAccept(listened);
1.11 ohara 186: return (fd < 0)? NULL: oxf_open(fd);
1.1 ohara 187: }
188:
189: #define LENGTH_OF_ONETIME_PASSWORD 64
190:
191: /* a password generator. */
192: char *generate_otp()
193: {
1.5 ohara 194: static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1.1 ohara 195: static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};
196: int i;
197:
198: srandom(time(NULL));
199: for(i=0; i<LENGTH_OF_ONETIME_PASSWORD; i++) {
200: otp[i] = crypto[random() % (sizeof(crypto)-1)];
201: }
202: return otp;
203: }
204:
205: /* proceeding a one time password. */
206: /* if the password is right,
207: then the function returns 1, if otherwise, then 0. */
208: int oxf_confirm_client(OXFILE *oxfp, char *passwd)
209: {
210: int len = strlen(passwd)+1;
211: char *buf = alloca(len);
212:
213: oxf_read(buf, 1, len, oxfp);
214: return !strcmp(passwd, buf);
215: }
216:
217: int oxf_confirm_server(OXFILE *oxfp, char *passwd)
218: {
219: return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);
220: }
221:
1.6 ohara 222: __inline__
223: static mathcap *oxf_mathcap(OXFILE *oxfp)
1.5 ohara 224: {
225: if (oxfp->mathcap == NULL) {
226: oxfp->mathcap = new_mathcap();
227: }
1.6 ohara 228: return oxfp->mathcap;
229: }
230:
231: cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp)
232: {
233: return mathcap_get(oxf_mathcap(oxfp));
234: }
235:
236: void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob)
237: {
238: mathcap_update(oxf_mathcap(oxfp), ob);
1.5 ohara 239: }
240:
1.1 ohara 241: /* example: which("xterm", getenv("PATH")); */
242: char *which(char *exe, const char *env)
243: {
244: char *tok;
245: char *path;
246: char delim[] = ":";
247: char *e = alloca(strlen(env)+1);
248: strcpy(e, env);
249: tok = strtok(e, delim);
250: while (tok != NULL) {
251: path = malloc(strlen(tok)+strlen(exe)+2);
252: sprintf(path, "%s/%s", tok, exe);
253: if (access(path, X_OK&R_OK) == 0) {
254: return path;
255: }
256: free(path);
257: tok = strtok(NULL, delim);
258: }
259: return NULL;
260: }
261:
262: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
263: int oxc_start(char *remote_host, short port, char *passwd)
264: {
265: char localhost[MAXHOSTNAMELEN];
266: char ports[128];
267: int pid = 0;
1.2 ohara 268: char *cmd = "oxc";
1.1 ohara 269:
270: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
271: if ((pid = fork()) == 0) {
272: sprintf(ports, "%d", port);
273: #ifdef DEBUG
274: fprintf(stderr, "oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
275: #endif
276: execlp("ssh", remote_host, "-f", cmd,
277: "-h", localhost, "-p", ports,"-c", passwd, NULL);
278: }
279: }
280: return pid;
1.8 ohara 281: }
282:
283: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
284: int oxc_start_with_pipe(char *remote_host, int port, char *passwd)
285: {
286: char localhost[MAXHOSTNAMELEN];
287: char ports[128];
288: int pid = 0;
289: char *cmd = "oxc";
290: int pipefd[2];
291:
292: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
293: if (pipe(pipefd) < 0) {
294: return -1;
295: }
296: if ((pid = fork()) == 0) {
297: dup2(pipefd[1], 0);
298: close(pipefd[0]);
299: close(pipefd[1]);
300: execlp("ssh", remote_host, cmd, NULL);
301: exit(1);
302: }
303: close(pipefd[1]);
304: pipe_send_info(pipefd[0], localhost, port, passwd);
305: }
306: return pid;
307: }
308:
309: static void pipe_send_string(int fd, char *s)
310: {
1.9 ohara 311: int len = strlen(s);
1.8 ohara 312: int lenN = htonl(len);
313: write(fd, &lenN, sizeof(int));
1.9 ohara 314: write(fd, s, len+1);
1.8 ohara 315: }
316:
317: static char *pipe_read_string()
318: {
319: int len;
320: char *s;
321: read(0, &len, sizeof(int));
1.9 ohara 322: len = ntohl(len)+1;
1.8 ohara 323: s = malloc(len);
324: read(0, s, len);
325: return s;
326: }
327:
1.9 ohara 328: /* The data format used by pipe_send_info() is defined in OX-RFC-101. */
1.8 ohara 329: void pipe_send_info(int fd, char *hostname, int port, char *password)
330: {
331: port = htonl(port);
332: write(fd, &port, sizeof(int));
333: pipe_send_string(fd, hostname);
334: pipe_send_string(fd, password);
335: }
336:
337: void pipe_read_info(char **hostname, int *port, char **password)
338: {
339: if (read(0, port, sizeof(int)) > 0) {
340: *port = ntohl(*port);
341: *hostname = pipe_read_string();
342: *password = pipe_read_string();
343: return 0;
344: }
345: return -1;
1.4 ohara 346: }
347:
348: /* Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
349: OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
350: {
1.5 ohara 351: short port = 0;
352: int listened;
1.4 ohara 353:
1.5 ohara 354: if ((listened = oxf_listen(&port)) != -1) {
1.10 ohara 355: cmo_list *args = list_appendl(NULL, list_append(new_cmo_list(), new_cmo_int32(port)), new_cmo_string(cmd), NULL);
356: send_ox_cmo(oxfp, (cmo *)args);
357: send_ox_command(oxfp, SM_control_spawn_server);
1.5 ohara 358: return oxf_connect_passive(listened);
359: }
360: return NULL;
1.1 ohara 361: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>