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