Annotation of OpenXM/src/ox_toolkit/oxf.c, Revision 1.15
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.15 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.14 2003/01/13 12:03:12 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);
1.14 ohara 273: ox_printf("oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
1.1 ohara 274: execlp("ssh", remote_host, "-f", cmd,
275: "-h", localhost, "-p", ports,"-c", passwd, NULL);
276: }
277: }
278: return pid;
1.8 ohara 279: }
280:
281: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
282: int oxc_start_with_pipe(char *remote_host, int port, char *passwd)
283: {
284: char localhost[MAXHOSTNAMELEN];
285: char ports[128];
286: int pid = 0;
287: char *cmd = "oxc";
288: int pipefd[2];
289:
290: if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
291: if (pipe(pipefd) < 0) {
292: return -1;
293: }
294: if ((pid = fork()) == 0) {
295: dup2(pipefd[1], 0);
296: close(pipefd[0]);
297: close(pipefd[1]);
298: execlp("ssh", remote_host, cmd, NULL);
299: exit(1);
300: }
301: close(pipefd[1]);
302: pipe_send_info(pipefd[0], localhost, port, passwd);
303: }
304: return pid;
305: }
306:
307: static void pipe_send_string(int fd, char *s)
308: {
1.9 ohara 309: int len = strlen(s);
1.8 ohara 310: int lenN = htonl(len);
311: write(fd, &lenN, sizeof(int));
1.9 ohara 312: write(fd, s, len+1);
1.8 ohara 313: }
314:
315: static char *pipe_read_string()
316: {
317: int len;
318: char *s;
319: read(0, &len, sizeof(int));
1.9 ohara 320: len = ntohl(len)+1;
1.8 ohara 321: s = malloc(len);
322: read(0, s, len);
323: return s;
324: }
325:
1.9 ohara 326: /* The data format used by pipe_send_info() is defined in OX-RFC-101. */
1.8 ohara 327: void pipe_send_info(int fd, char *hostname, int port, char *password)
328: {
329: port = htonl(port);
330: write(fd, &port, sizeof(int));
331: pipe_send_string(fd, hostname);
332: pipe_send_string(fd, password);
333: }
334:
335: void pipe_read_info(char **hostname, int *port, char **password)
336: {
337: if (read(0, port, sizeof(int)) > 0) {
338: *port = ntohl(*port);
339: *hostname = pipe_read_string();
340: *password = pipe_read_string();
341: return 0;
342: }
343: return -1;
1.4 ohara 344: }
345:
346: /* Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
347: OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
348: {
1.5 ohara 349: short port = 0;
350: int listened;
1.4 ohara 351:
1.5 ohara 352: if ((listened = oxf_listen(&port)) != -1) {
1.10 ohara 353: cmo_list *args = list_appendl(NULL, list_append(new_cmo_list(), new_cmo_int32(port)), new_cmo_string(cmd), NULL);
354: send_ox_cmo(oxfp, (cmo *)args);
355: send_ox_command(oxfp, SM_control_spawn_server);
1.5 ohara 356: return oxf_connect_passive(listened);
357: }
358: return NULL;
1.1 ohara 359: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>